[jboss-cvs] JBossAS SVN: r60243 - branches/Branch_4_2/security/src/main/org/jboss/security/jndi.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Feb 3 14:05:45 EST 2007


Author: scott.stark at jboss.org
Date: 2007-02-03 14:05:45 -0500 (Sat, 03 Feb 2007)
New Revision: 60243

Modified:
   branches/Branch_4_2/security/src/main/org/jboss/security/jndi/JndiLoginInitialContextFactory.java
   branches/Branch_4_2/security/src/main/org/jboss/security/jndi/SecurityAssociationActions.java
Log:
JBAS-2523, multi-threaded and restoreIdentity option work

Modified: branches/Branch_4_2/security/src/main/org/jboss/security/jndi/JndiLoginInitialContextFactory.java
===================================================================
--- branches/Branch_4_2/security/src/main/org/jboss/security/jndi/JndiLoginInitialContextFactory.java	2007-02-03 18:53:45 UTC (rev 60242)
+++ branches/Branch_4_2/security/src/main/org/jboss/security/jndi/JndiLoginInitialContextFactory.java	2007-02-03 19:05:45 UTC (rev 60243)
@@ -26,6 +26,11 @@
 
 import javax.naming.Context;
 import javax.naming.NamingException;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.security.Principal;
 import java.util.Hashtable;
 
@@ -64,6 +69,20 @@
       Object credentials = env.get(Context.SECURITY_CREDENTIALS);
       Object principal = env.get(Context.SECURITY_PRINCIPAL);
       Principal securityPrincipal = null;
+      /** Flag indicating if the SecurityAssociation existing at login should
+      be restored on logout.
+      */
+      String flag = (String) env.get("jnp.multi-threaded");
+      if (Boolean.valueOf(flag).booleanValue() == true)
+      {
+         /* Turn on the server mode which uses thread local storage for
+            the principal information.
+         */
+         SecurityAssociationActions.setServer();
+      }
+      boolean restoreLoginIdentity = false;
+      if( flag != null )
+         restoreLoginIdentity = Boolean.parseBoolean(flag);
       // See if the principal is a Principal or String
       if( principal instanceof Principal )
       {
@@ -76,10 +95,65 @@
          securityPrincipal = new SimplePrincipal(username);
       }
       // Associate this security context
-      SecurityAssociationActions.setPrincipalInfo(securityPrincipal, credentials);
+      if( restoreLoginIdentity )
+      {
+         SecurityAssociationActions.setPrincipalInfo(securityPrincipal, credentials);
+      }
+      else
+      {
+         SecurityAssociationActions.setPrincipalInfo(securityPrincipal, credentials);
+      }
       // Now return the context using the standard jnp naming context factory
       Context iniCtx = super.getInitialContext(env);
+      if( restoreLoginIdentity )
+      {
+         // Use a proxy to pop the stack when the context is closed
+         ClassLoader loader = SecurityAssociationActions.getContextClassLoader();
+         ContextProxy handler = new ContextProxy(iniCtx);
+         Class[] ifaces = {Context.class};
+         iniCtx = (Context) Proxy.newProxyInstance(loader, ifaces, handler);
+      }
       return iniCtx;
    }
 
+   /**
+    * 
+    */
+   public static class ContextProxy implements InvocationHandler
+   {
+      private Context delegate;
+      ContextProxy(Context delegate)
+      {
+         this.delegate = delegate;
+      }
+      public Object invoke(Object proxy, Method method, Object[] args)
+         throws Throwable
+      {
+         boolean close = false;
+         try
+         {
+            close = method.getName().equals("close");
+            return method.invoke(delegate, args);
+         }
+         catch(InvocationTargetException e)
+         {
+            throw e.getTargetException();
+         }
+         finally
+         {
+            if( close )
+            {
+               // Pop the security context on close
+               try
+               {
+                  SecurityAssociationActions.popPrincipalInfo();
+               }
+               catch(Throwable ignore)
+               {
+               }
+            }
+         }
+      }
+      
+   }
 }

Modified: branches/Branch_4_2/security/src/main/org/jboss/security/jndi/SecurityAssociationActions.java
===================================================================
--- branches/Branch_4_2/security/src/main/org/jboss/security/jndi/SecurityAssociationActions.java	2007-02-03 18:53:45 UTC (rev 60242)
+++ branches/Branch_4_2/security/src/main/org/jboss/security/jndi/SecurityAssociationActions.java	2007-02-03 19:05:45 UTC (rev 60243)
@@ -37,6 +37,27 @@
  */
 class SecurityAssociationActions
 {
+   private static class SetPrincipalInfoStackAction implements PrivilegedAction
+   {
+      Principal principal;
+      Object credential;
+      Subject subject;
+      SetPrincipalInfoStackAction(Principal principal, Object credential, Subject subject)
+      {
+         this.principal = principal;
+         this.credential = credential;
+         this.subject = subject;
+      }
+      public Object run()
+      {
+         SecurityAssociation.pushSubjectContext(subject, principal, credential);
+         credential = null;
+         principal = null;
+         subject = null;
+         return null;
+      }
+   }
+
    private static class SetPrincipalInfoAction implements PrivilegedAction
    {
       Principal principal;
@@ -55,11 +76,58 @@
          return null;
       }
    }
+   private static class PopPrincipalInfoAction implements PrivilegedAction
+   {
+      public Object run()
+      {
+         SecurityAssociation.popSubjectContext();
+         return null;
+      }
+   }
 
+   private static class GetTCLAction implements PrivilegedAction
+   {
+      static PrivilegedAction ACTION = new GetTCLAction();
+      public Object run()
+      {
+         ClassLoader loader = Thread.currentThread().getContextClassLoader();
+         return loader;
+      }
+   }
+
+   private static class SetServerAction implements PrivilegedAction
+   {
+      static PrivilegedAction ACTION = new SetServerAction();
+      public Object run()
+      {
+         SecurityAssociation.setServer();
+         return null;
+      }
+   }
    static void setPrincipalInfo(Principal principal, Object credential)
    {
       SetPrincipalInfoAction action = new SetPrincipalInfoAction(principal, credential);
       AccessController.doPrivileged(action);
    }
+   static void setPrincipalInfo(Principal principal, Object credential, Subject subject)
+   {
+      SetPrincipalInfoStackAction action = new SetPrincipalInfoStackAction(principal, credential, subject);
+      AccessController.doPrivileged(action);
+   }
+   static void popPrincipalInfo()
+   {
+      PopPrincipalInfoAction action = new PopPrincipalInfoAction();
+      AccessController.doPrivileged(action);
+   }
 
+   static void setServer()
+   {
+      AccessController.doPrivileged(SetServerAction.ACTION);
+   }
+   static ClassLoader getContextClassLoader()
+   {
+      ClassLoader loader = (ClassLoader) AccessController.doPrivileged(GetTCLAction.ACTION);
+      return loader;
+   }
+
 }




More information about the jboss-cvs-commits mailing list