Announcement Announcement Module
Collapse
No announcement yet.
securityContext.getAuthentication() is null in a Thread Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • securityContext.getAuthentication() is null in a Thread

    Hi there,

    In our webapp, we have something like this

    SomeServiceClass {
    private Executor taskExecutor; // gets set in a private method for now, but will be injected by spring xml later on.
    doSomething() {
    taskExecutor.execute( new Runnable() {
    public void run() {
    doNotify(some_final_string);
    }
    });
    }

    doNotify(final String xyz) {
    SecurityContext securityContext = SecurityContextHolder.getContext();

    // this always returns null in asynch mode but works in non-asynch mode.
    securityContext.getAuthentication() ;

    }
    }

    any idea why securityContext.getAuthentication() always returns null?

    2nd question.

    we've a PortalLogoutHandler class that implements Spring LogoutHandler
    in public void logout( HttpServletRequest request, HttpServletResponse response, Authentication authentication ), we need to do something with authentication, but it's null by the time logout is called. Is there a preLogout() we can use ? another way to ask the question, if we need to do something with the authentication object prior to its being nullified, how can we achieve that?

    thanks

  • #2
    SecurityContextHolder runs off thread local. You're starting a new thread when you go asynch.

    Comment


    • #3
      So what's the solution?

      I am having the same issue. We have several cron jobs set up through Spring that are failing because we can't authenticate in this situation.

      Comment


      • #4
        Section 5.2.1 in touches on this topic at http://static.springsource.org/sprin...-overview.html .

        But I would check to see that you have to do this. I'm having trouble thinking of a usecase where I would need access to a currently authenticated user to trigger a cron task.

        Comment


        • #5
          Originally posted by arthomps View Post
          Section 5.2.1 in touches on this topic at http://static.springsource.org/sprin...-overview.html .

          But I would check to see that you have to do this. I'm having trouble thinking of a usecase where I would need access to a currently authenticated user to trigger a cron task.
          So here's my scenario....

          A cron job is set to clean up orphaned documents. To retrieve a list of documents I need to query our database for a list of the documents. We have an AOP pointcut setup to check the Authentication object of the user prior to executing the DB query through Hibernate. In this case the user is our "server" user or in other words the account which is running our web app. In this case the Authentication object is null and therefor the cron job never gets performed because we can't authenticate our server user. We have to authenticate against a propietary user database and cannot add this server user. But the server does have a Server PKI which could possible be used but I am not sure how to handle this.

          Is there a good way to handle this or any other suggestions?

          Comment


          • #6
            did you try the link i provided? SecurityContextHolder.MODE_INHERITABLETHREADLOCAL sounds like what you're looking for.

            Comment


            • #7
              securityContext.getAuthentication() is null in a Thread

              Got it. I will try that. Thanks!

              Comment


              • #8
                Unfortunately SecurityContextHolder.MODE_INHERITABLETHREADLOCAL didn't work. I found this note which may explain why:

                "Note however, that you cannot share security context among sibling threads (e.g. in a thread pool). This method only works for child threads that are spawned by a thread that already contains a populated SecurityContext."

                I guess since the server process is spawning this thread it is a "sibling" thread. I guess I am going to resort to reading in the server certificate and using it to populate an Auth object and then perform the work. I would rather have set this up through Spring but it doesn't seem like anybody knows how to do this.

                Comment


                • #9
                  You could create a Runnable that sets the Authentication or SecurityContext to use one that is injected and then delegate to the Runnable you actually want. Something like...

                  Code:
                  public class SpringSecurityRunnableWrapper implements Runnable {
                    private SecurityContext context;
                    private Runnable delegate;
                   
                    public SpringSecurityRunnableWrapper(SecurityContext context, Runnable delegate) {
                      this.context = context;
                      this.delegate = delegate;
                    }
                  
                    public void run() {    
                      try {
                        SecurityContextHolder.setContext(context);
                        delegate.run();
                      } finally {
                        SecurityContextHolder.clear();
                      }
                  }
                  Then to call it you would do something like:

                  Code:
                  Runnable worker = new MyCustomRunnableThatNeedsSecurity();
                  SecurityContext context = new SecurityContextImpl();
                  context.setAuthentication(new UsernamePasswordAuthenticationToken("username","password",AuthorityUtils.createAuthorityList("ROLE_USER"));
                  Runnable securedWorker = new SpringSecurityRunnableWrapper(context, worker);
                  taskExecutor.execute(securedWorker);
                  Of Course you don't really need SpringSecurityRunnableWrapper since you could manage the SecurityContext inside of MyCustomRunnableThatNeedsSecurity directly, but it makes this more reusable and separates concerns.

                  Comment

                  Working...
                  X