0 Replies Latest reply on May 2, 2006 12:25 PM by jwynett

    Problem AuthenticationInterceptor and SecurityAssociation st

    jwynett

      I've just noticed a problem that seems to be in both 4.0.4 CR2 and RC1 where the subjectContext stack keeps growing from invocation to invocation on individual threads. A side effect of this problem is that it is possible for a thread to stay authenticated from one client call to the next. I can reproduce this side effect in my main application although have not been able to do so in a simple test case.

      I've tracked it to the org.jboss.aspects.security.AuthenticationInterceptor invoke method (shown below). You'll notice in the finally block it sets the principal and credential to null. What this does is add a null entry to the stack when I think what is intended is to clear the stack. The end result is on each invocation chain, a new 'null' entry is added to the stack that is never removed and it grows and grows. This can be compounded if the application code logs in users that are never logged out. They never get removed from the stack either.

      I don't really know how to fix this as I don't really understand the flow of the invocation.metaData and the code in general to find a point to do this without unintentionally screwing up something else. Ideally, when the server knows a thread is finished, it should clear the stack, however you don't want to do this too early at a point when the app thinks it should still be logged in.

      I tried replacing the setPrincipal and setCredential in the finally block with SecurityAssociation.clear() and this helped but not in all circumstances since that block of code may not be executed. I have found a case where the metadata.security.principal turns up null in the finally block: if a client is not logged in and calls a 'PermitAll' method in the server, which then goes on internally to log in a user but not log it out, the code is not executed and the SecurityAssociation doesn't get cleared.

      On the flip side, you don't want this called all the time or it will clear the stack when it shouldn't be cleared causing potential insufficient permissions errors.

      
       /**
       * Authenticates the caller using the principal and credentials in the
       * Infocation if thre is a security manager and an invcocation method.
       */
       public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable
       {
       try
       {
       authenticate(invocation);
       }
       catch (GeneralSecurityException gse)
       {
       handleGeneralSecurityException(gse);
       }
      
       Object oldDomain = SecurityContext.currentDomain.get();
       try
       {
       SecurityContext.currentDomain.set(authenticationManager);
       return invocation.invokeNext();
       }
       finally
       {
       SecurityContext.currentDomain.set(oldDomain);
       // so that the principal doesn't keep being associated with thread if the thread is pooled
       SecurityAssociation.popSubjectContext();
      
       if (invocation.getMetaData("security", "principal") != null)
       {
       SecurityAssociation.setPrincipal(null);
       SecurityAssociation.setCredential(null);
       }
       }
       }