Authentication security using Shiro breaks CLI

30 views
Skip to first unread message

lennyi

unread,
Feb 7, 2017, 12:48:59 AM2/7/17
to puppet-razor
Hello,
We recently enabled authentication security using Shiro and now find that we can no longer use the razor cli.  How do we pass credentials to the cli without doing something like the below?

razor -u https://user:password@razorserver/api/...

Additionally, after enabling the localhost to bypass authentication, we found that from the razor server read-only commands worked (i.e., razor nodes), but create/update/register/delete commands no longer worked.  We would get a 500 error as follows:

from /var/log/puppetlabs/razor-server/server.log:

15:35:35,274 INFO  [razor.web.log] (http-/0.0.0.0:8151-3) 127.0.0.1 - - [03/Feb/2017:15:35:35 -0600] "GET /api " 200 6629 0.0120
15:35:35,356 INFO  [razor.web.log] (http-/0.0.0.0:8151-3) 127.0.0.1 - - [03/Feb/2017:15:35:35 -0600] "GET /api/commands/register-node " 200 6205 0.0140
15:35:35,419 INFO  [razor.web.api] (http-/0.0.0.0:8151-2) 2017-02-03 15:35:35 - Java::OrgApacheShiroAuthz::UnauthenticatedException - This subject is anonymous - it does not have any identifying principals and authorization operations require an identity to check against.  A Subject instance will acquire these identifying principals automatically after a successful login is performed be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' functionality is enabled by the SecurityManager.  This exception can also occur when a previously logged-in Subject has logged out which makes it anonymous again.  Because an identity is currently not known due to any of these conditions, authorization is denied.:
org.apache.shiro.subject.support.DelegatingSubject.assertAuthzCheckPossible(org/apache/shiro/subject/support/DelegatingSubject.java:199)
org.apache.shiro.subject.support.DelegatingSubject.checkPermissions(org/apache/shiro/subject/support/DelegatingSubject.java:214)
java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498)
RUBY.validate!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/validation/hash_schema.rb:149)
RUBY.validate!(/opt/puppetlabs/server/apps/razor-server/share/torquebox/jruby/lib/ruby/1.9/forwardable.rb:201)
RUBY.handle_http_post(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/command.rb:33)
RUBY.POST /api/commands/:name(/opt/puppetlabs/server/apps/razor-server/share/razor-server/app.rb:610)
org.jruby.RubyMethod.call(org/jruby/RubyMethod.java:124)
RUBY.compile!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1610)
org.jruby.RubyProc.call(org/jruby/RubyProc.java:271)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:974)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:974)
Sinatra::Base.route_eval(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:993)
Sinatra::Base.route_eval(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:993)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:974)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:974)
Sinatra::Base.process_route(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1014)
Sinatra::Base.process_route(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1014)
org.jruby.RubyKernel.catch(org/jruby/RubyKernel.java:1264)
Sinatra::Base.process_route(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1012)
Sinatra::Base.process_route(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1012)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:972)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:972)
org.jruby.RubyArray.each(org/jruby/RubyArray.java:1613)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:971)
Sinatra::Base.route!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:971)
Sinatra::Base.dispatch!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1084)
Sinatra::Base.dispatch!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1084)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
org.jruby.RubyKernel.catch(org/jruby/RubyKernel.java:1264)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
Sinatra::Base.dispatch!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1081)
Sinatra::Base.dispatch!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1081)
Sinatra::Base.call!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:906)
Sinatra::Base.call!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:906)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
org.jruby.RubyKernel.catch(org/jruby/RubyKernel.java:1264)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
Sinatra::Base.invoke(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:1066)
Sinatra::Base.call!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:906)
Sinatra::Base.call!(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:906)
Sinatra::Base.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:894)
Sinatra::Base.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:894)
Razor::Middleware::Auth.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/middleware/auth.rb:52)
Razor::Middleware::Auth.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/middleware/auth.rb:52)
Razor::Middleware::Auth.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/middleware/auth.rb:50)
Razor::Middleware::Auth.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/middleware/auth.rb:50)
Rack::CommonLogger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-1.6.1/lib/rack/commonlogger.rb:33)
Rack::CommonLogger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-1.6.1/lib/rack/commonlogger.rb:33)
Rack::CommonLogger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:218)
Rack::CommonLogger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:218)
Razor::Middleware::Logger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/middleware/logger.rb:13)
Razor::Middleware::Logger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/lib/razor/middleware/logger.rb:13)
Rack::Protection::XSSHeader.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18)
Rack::Protection::XSSHeader.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18)
Rack::Protection::PathTraversal.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16)
Rack::Protection::PathTraversal.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16)
Rack::Protection::JsonCsrf.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18)
Rack::Protection::JsonCsrf.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18)
Rack::Protection::Base.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49)
Rack::Protection::Base.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49)
Rack::Protection::Base.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49)
Rack::Protection::Base.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49)
Rack::Protection::FrameOptions.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31)
Rack::Protection::FrameOptions.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31)
Rack::NullLogger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-1.6.1/lib/rack/nulllogger.rb:9)
Rack::NullLogger.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-1.6.1/lib/rack/nulllogger.rb:9)
Rack::Head.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-1.6.1/lib/rack/head.rb:13)
Rack::Head.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/rack-1.6.1/lib/rack/head.rb:13)
Sinatra::ExtendedRack.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:181)
Sinatra::ExtendedRack.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:181)
Sinatra::Wrapper.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:2021)
Sinatra::Wrapper.call(/opt/puppetlabs/server/apps/razor-server/share/razor-server/vendor/bundle/jruby/1.9/gems/sinatra-1.4.6/lib/sinatra/base.rb:2021)
org.torquebox.core.util.RuntimeHelper$3.call(org/torquebox/core/util/RuntimeHelper.java:91)
org.torquebox.core.util.RuntimeHelper.withinContext(org/torquebox/core/util/RuntimeHelper.java:264)
org.torquebox.core.util.RuntimeHelper.call(org/torquebox/core/util/RuntimeHelper.java:89)
org.torquebox.core.component.AbstractRubyComponent._callRubyMethod(org/torquebox/core/component/AbstractRubyComponent.java:64)
org.torquebox.core.component.AbstractRubyComponent._callRubyMethod(org/torquebox/core/component/AbstractRubyComponent.java:73)
org.torquebox.web.component.RackApplicationComponent.call(org/torquebox/web/component/RackApplicationComponent.java:38)
org.torquebox.web.servlet.RackFilter.doRack(org/torquebox/web/servlet/RackFilter.java:155)
org.torquebox.web.servlet.RackFilter.doFilter(org/torquebox/web/servlet/RackFilter.java:138)
org.torquebox.web.servlet.RackFilter.doFilter(org/torquebox/web/servlet/RackFilter.java:96)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(org/apache/catalina/core/ApplicationFilterChain.java:246)
org.apache.catalina.core.ApplicationFilterChain.doFilter(org/apache/catalina/core/ApplicationFilterChain.java:214)
org.torquebox.web.servlet.SendfileFilter.doFilter(org/torquebox/web/servlet/SendfileFilter.java:49)
org.torquebox.web.servlet.SendfileFilter.doFilter(org/torquebox/web/servlet/SendfileFilter.java:33)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(org/apache/catalina/core/ApplicationFilterChain.java:246)
org.apache.catalina.core.ApplicationFilterChain.doFilter(org/apache/catalina/core/ApplicationFilterChain.java:214)
org.apache.catalina.core.StandardWrapperValve.invoke(org/apache/catalina/core/StandardWrapperValve.java:230)
org.apache.catalina.core.StandardContextValve.invoke(org/apache/catalina/core/StandardContextValve.java:149)
org.jboss.as.web.security.SecurityContextAssociationValve.invoke(org/jboss/as/web/security/SecurityContextAssociationValve.java:169)
org.apache.catalina.core.StandardHostValve.invoke(org/apache/catalina/core/StandardHostValve.java:145)
org.apache.catalina.valves.ErrorReportValve.invoke(org/apache/catalina/valves/ErrorReportValve.java:97)
org.apache.catalina.core.StandardEngineValve.invoke(org/apache/catalina/core/StandardEngineValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(org/apache/catalina/connector/CoyoteAdapter.java:336)
org.apache.coyote.http11.Http11Processor.process(org/apache/coyote/http11/Http11Processor.java:856)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(org/apache/coyote/http11/Http11Protocol.java:653)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(org/apache/tomcat/util/net/JIoEndpoint.java:920)
java.lang.Thread.run(java/lang/Thread.java:745)
15:35:35,422 INFO  [razor.web.log] (http-/0.0.0.0:8151-2) 127.0.0.1 - - [03/Feb/2017:15:35:35 -0600] "POST /api/commands/register-node " 500 30 0.0130

Our environment variables:
profile.d # cat razor_env.sh
# Razor Client Environment Variables
export RAZOR_HOSTNAME=razor.lan.local
export HTTP_PORT=8150
export HTTPS_PORT=8151

PATH=$PATH:$HOME/bin:/opt/puppetlabs/puppet/bin

Thank you for any assistance you can provide.  Let me know if I should post a JIRA issue.

Lenny

lennyi

unread,
Feb 7, 2017, 2:00:01 PM2/7/17
to puppet-razor
Update: 
We found that by adding the username:password into the RAZOR_API environment variable, we can successfully run razor commands with authentication.  Although keeping the razor creds in an environment variable / bash_profile script is not ideal, this is the workaround we came up with.  Would like to see a more secure way of authenticating against razor via the razor cli in the near future.  Is there something on the roadmap for this?


The second issue I mentioned above regarding not being to run create/update/delete/register commands from the razor server after enabling localhost auth bypass is still something we would like to get an answer on.

Thanks,
Lenny

Scott McClellan

unread,
Feb 17, 2017, 2:10:34 PM2/17/17
to puppet-razor
Hi Lenny,

Thanks for pointing this out. I've created a pull request which will fix this oversight here:


I'll get it merged and included in the next release.

As for the second ticket around token auth for the client, that's a feature which will take a bit more scoping out. I've left a comment on that ticket for further discussion.

Thanks again for your involvement!

Scott

--
You received this message because you are subscribed to the Google Groups "puppet-razor" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-razor...@googlegroups.com.
To post to this group, send email to puppet...@googlegroups.com.
Visit this group at https://groups.google.com/group/puppet-razor.
For more options, visit https://groups.google.com/d/optout.
--
-- 
Reply all
Reply to author
Forward
0 new messages