[jboss-cvs] JBossAS SVN: r62258 - in trunk/server/src/main/org/jboss: ejb/plugins/local and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Apr 11 12:30:46 EDT 2007


Author: anil.saldhana at jboss.com
Date: 2007-04-11 12:30:46 -0400 (Wed, 11 Apr 2007)
New Revision: 62258

Added:
   trunk/server/src/main/org/jboss/proxy/SecurityActions.java
Modified:
   trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
   trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java
   trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java
   trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
   trunk/server/src/main/org/jboss/invocation/Invocation.java
   trunk/server/src/main/org/jboss/invocation/InvocationKey.java
   trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java
   trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java
   trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java
Log:
JBAS-43217:SecurityContext over the invocation

Modified: trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -20,27 +20,35 @@
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
 package org.jboss.ejb.plugins;
-
+ 
 import org.jboss.ejb.Container;
 import org.jboss.invocation.Invocation;
 import org.jboss.metadata.ApplicationMetaData;
 import org.jboss.metadata.AssemblyDescriptorMetaData;
 import org.jboss.metadata.BeanMetaData;
 import org.jboss.metadata.SecurityIdentityMetaData;
-import org.jboss.security.RunAsIdentity;
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.RunAsIdentity; 
 
 import java.util.Set;
 
 /**
  * An interceptor that enforces the run-as identity declared by a bean.
+ * 
+ * Mainly used by MDB containers
  *
  * @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>.
  * @author <a href="mailto:Thomas.Diesler at jboss.org">Thomas Diesler</a>.
+ * @author Anil.Saldhana at redhat.com
  * @version $Revision$
  */
 public class RunAsSecurityInterceptor extends AbstractInterceptor
 {
-   protected RunAsIdentity runAsIdentity;
+   protected RunAsIdentity runAsIdentity; 
+   
+   /** The authentication manager plugin
+    */
+   protected AuthenticationManager securityManager;
 
    public RunAsSecurityInterceptor()
    {
@@ -70,6 +78,8 @@
             Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
             runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
          }
+
+         securityManager = container.getSecurityManager();
       }
    }
 
@@ -81,11 +91,21 @@
 
    public Object invokeHome(Invocation mi) throws Exception
    {
+      String securityDomain = securityManager != null ? securityManager.getSecurityDomain()
+                                                                                      :"EMPTY";
+      //Establish a security context if one is missing for Run-As push
+      if(SecurityActions.getSecurityContext() == null)
+      {
+         SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+               mi.getCredential(), securityDomain);
+      }
+      
       /* If a run-as role was specified, push it so that any calls made
        by this bean will have the runAsRole available for declarative
        security checks.
       */
-      SecurityActions.pushRunAsIdentity(runAsIdentity);
+      SecurityActions.pushRunAsIdentity(runAsIdentity); 
+      
       try
       {
          Object returnValue = getNext().invokeHome(mi);
@@ -99,11 +119,20 @@
 
    public Object invoke(Invocation mi) throws Exception
    {
+      String securityDomain = securityManager != null ? securityManager.getSecurityDomain()
+            :"EMPTY";
+      //Establish a security context if one is missing for Run-As push
+      if(SecurityActions.getSecurityContext() == null)
+      {
+         SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+               mi.getCredential(), securityDomain);
+      }
+      
       /* If a run-as role was specified, push it so that any calls made
        by this bean will have the runAsRole available for declarative
        security checks.
       */
-      SecurityActions.pushRunAsIdentity(runAsIdentity);
+      SecurityActions.pushRunAsIdentity(runAsIdentity); 
       try
       {
          Object returnValue = getNext().invoke(mi);

Modified: trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -36,8 +36,13 @@
 import org.jboss.security.SecurityAssociation;
 import org.jboss.security.RunAsIdentity;
 import org.jboss.security.SecurityConstants;
-import org.jboss.security.SecurityContext; 
+import org.jboss.security.SecurityContext;  
+import org.jboss.security.SubjectInfo;
+import org.jboss.security.plugins.SecurityContextAssociation;
+import org.jboss.security.plugins.SecurityContextFactory;
 
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
 /** A collection of privileged actions for this package
  * @author Scott.Stark at jboss.org
  * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
@@ -128,7 +133,9 @@
          {
             public Object run()
             {
-               return SecurityAssociation.popRunAsIdentity();
+               //return SecurityAssociation.popRunAsIdentity();
+               SecurityContext sc = SecurityContextAssociation.getSecurityContext(); 
+               return sc.getUtil().remove(sc,RUNAS_IDENTITY_IDENTIFIER);
             }
          };
 
@@ -152,7 +159,7 @@
          }
 
          public RunAsIdentity pop()
-         {
+         { 
             return (RunAsIdentity)AccessController.doPrivileged(popAction);
          }
       };
@@ -166,12 +173,19 @@
 
          public void push(RunAsIdentity id)
          {
-            SecurityAssociation.pushRunAsIdentity(id);
+            //SecurityAssociation.pushRunAsIdentity(id); 
+            SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+            if(sc == null)
+               throw new IllegalStateException("Security Context is null to push runas"); 
+            sc.getUtil().set(sc, RUNAS_IDENTITY_IDENTIFIER, id);
          }
 
          public RunAsIdentity pop()
-         {
-            return SecurityAssociation.popRunAsIdentity();
+         { 
+            //Pop the RAI 
+            // return SecurityAssociation.popRunAsIdentity(); 
+            SecurityContext sc = SecurityContextAssociation.getSecurityContext(); 
+            return sc.getUtil().remove(sc,RUNAS_IDENTITY_IDENTIFIER);
          }
       };
 
@@ -495,7 +509,8 @@
             SecurityAssociation.setContextInfo(sc, map);
          }
          SecurityAssociation.setContextInfo(sc, map);  
-         return map.get(this.securityDomain); 
+         //return map.get(this.securityDomain); 
+         return SecurityContextAssociation.getSecurityContext();
       }
    }
    
@@ -520,6 +535,8 @@
          }
          map.put(securityDomain, securityContext); 
          SecurityAssociation.setContextInfo(sc, map); 
+         
+         SecurityContextAssociation.setSecurityContext(securityContext);
          return null;
       }
    }
@@ -547,13 +564,50 @@
          return null;
       }
    }
+   
+   static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain)
+   {
+      AccessController.doPrivileged(new PrivilegedAction(){
 
+         public Object run()
+         {
+            SecurityContext sc = SecurityContextFactory.createSecurityContext(p, cred, null, domain);
+            SecurityContextAssociation.setSecurityContext(sc);
+            return null;
+         }});
+   }
+   
+   static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain,
+         final Subject subject)
+   {
+      AccessController.doPrivileged(new PrivilegedAction(){
+
+         public Object run()
+         {
+            SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
+            SubjectInfo si = SecurityContextFactory.createSubjectInfo(p, cred, subject);  
+            sc.setSubjectInfo(si);
+            SecurityContextAssociation.setSecurityContext(sc);
+            return null;
+         }});
+   }
+
    static void clearSecurityContext(String securityDomain)
    {
       ClearSecurityContextAction action = new ClearSecurityContextAction(securityDomain);
       AccessController.doPrivileged(action);
    }
    
+   static SecurityContext getSecurityContext()
+   { 
+      return (SecurityContext)AccessController.doPrivileged(new PrivilegedAction(){
+         public Object run()
+         {
+            return SecurityContextAssociation.getSecurityContext();
+         }
+      });
+   }
+   
    static SecurityContext getSecurityContext(String securityDomain)
    {
       GetSecurityContextAction action = new GetSecurityContextAction(securityDomain);

Modified: trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -21,8 +21,12 @@
 */
 package org.jboss.ejb.plugins;
 
+import static org.jboss.security.SecurityConstants.DEFAULT_EJB_APPLICATION_POLICY;
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
 import org.jboss.ejb.Container;
 import org.jboss.invocation.Invocation; 
+import org.jboss.invocation.InvocationKey; 
 import org.jboss.metadata.ApplicationMetaData;
 import org.jboss.metadata.AssemblyDescriptorMetaData;
 import org.jboss.metadata.BeanMetaData;
@@ -30,19 +34,17 @@
 import org.jboss.security.AuthenticationManager;
 import org.jboss.security.AuthorizationManager;
 import org.jboss.security.RealmMapping;
-import org.jboss.security.RunAsIdentity;
-import org.jboss.security.SecurityConstants;  
+import org.jboss.security.RunAsIdentity;  
 import org.jboss.security.SecurityContext; 
-import org.jboss.security.SecurityRolesAssociation;
-import org.jboss.security.SecurityContext.SubjectInfo;
-import org.jboss.security.audit.AuditContext;
+import org.jboss.security.SecurityRolesAssociation; 
+import org.jboss.security.Util;
 import org.jboss.security.audit.AuditEvent;
 import org.jboss.security.audit.AuditLevel; 
 import org.jboss.security.audit.AuditManager;
+import org.jboss.security.audit.SecurityAuditManager;
 import org.jboss.security.authorization.AuthorizationContext;
 import org.jboss.security.authorization.EJBResource;
-import org.jboss.security.authorization.ResourceKeys; 
-import org.jboss.security.plugins.JBossSecurityContext;
+import org.jboss.security.authorization.ResourceKeys;  
 import org.jboss.system.Registry; 
 
 import java.security.CodeSource;
@@ -110,7 +112,13 @@
     */
    protected String appSecurityDomain = null; 
    //Fallback Security Domain
-   protected String defaultAuthorizationSecurityDomain = SecurityConstants.DEFAULT_EJB_APPLICATION_POLICY;  
+   protected String defaultAuthorizationSecurityDomain = DEFAULT_EJB_APPLICATION_POLICY;  
+   
+   /**
+    * Specify whether <use-caller-identity> is configured, mainly
+    * for the use case of caller identity coming with run-as
+    */
+   protected boolean isUseCallerIdentity = false;
     
    /** Called by the super class to set the container to which this interceptor
     belongs. We obtain the security manager and runAs identity to use here.
@@ -136,6 +144,9 @@
             Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
             runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
          }
+         
+         if (secMetaData != null && secMetaData.getUseCallerIdentity())
+            this.isUseCallerIdentity = true;
 
          securityManager = container.getSecurityManager();
          realmMapping = container.getRealmMapping();
@@ -150,7 +161,11 @@
          {
          }
          //Authorization Framework changes
-         appSecurityDomain = applicationMetaData.getSecurityDomain();
+         if(securityManager != null)
+         {
+            appSecurityDomain =  securityManager.getSecurityDomain();
+            appSecurityDomain = Util.unprefixSecurityDomain(appSecurityDomain); 
+         } 
          ejbName = beanMetaData.getEjbName();  
          ejbCS = container.getBeanClass().getProtectionDomain().getCodeSource(); 
       }
@@ -167,13 +182,29 @@
    public Object invokeHome(Invocation mi) throws Exception
    {  
       // Authenticate the subject and apply any declarative security checks
-      checkSecurityAssociation(mi);
+      checkSecurityAssociation(mi); 
+      
+      //Establish a security context if one is missing for Run-As push
+      if(SecurityActions.getSecurityContext() == null)
+      {
+         SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+               mi.getCredential(), this.appSecurityDomain);
+      }
+      
+      RunAsIdentity callerRunAsIdentity = getCallerRunAsIdentity(mi);  
+      /**
+       * Special case: if <use-caller-identity> configured and
+       * the caller is arriving with a run-as, we need to push that run-as
+       */
+      if(callerRunAsIdentity != null && this.isUseCallerIdentity)
+         this.runAsIdentity = callerRunAsIdentity;
+      
 
       /* If a run-as role was specified, push it so that any calls made
        by this bean will have the runAsRole available for declarative
        security checks.
       */
-      SecurityActions.pushRunAsIdentity(runAsIdentity);
+      SecurityActions.pushRunAsIdentity(runAsIdentity); 
 
       try
       { 
@@ -185,21 +216,36 @@
          SecurityActions.popRunAsIdentity(); 
          SecurityActions.popSubjectContext();
          //Clear the SecurityContext
-         SecurityActions.clearSecurityContext(appSecurityDomain);
+         SecurityActions.clearSecurityContext(appSecurityDomain); 
       }
    }
 
 
    public Object invoke(Invocation mi) throws Exception
-   {  
+   {   
       // Authenticate the subject and apply any declarative security checks
       checkSecurityAssociation(mi);
 
+      //Establish a security context if one is missing for Run-As push
+      if(SecurityActions.getSecurityContext() == null)
+      {
+         SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+               mi.getCredential(), this.appSecurityDomain);
+      }
+      
+      RunAsIdentity callerRunAsIdentity = getCallerRunAsIdentity(mi);  
+      /**
+       * Special case: if <use-caller-identity> configured and
+       * the caller is arriving with a run-as, we need to push that run-as
+       */
+      if(callerRunAsIdentity != null && this.isUseCallerIdentity)
+         this.runAsIdentity = callerRunAsIdentity;
+      
       /* If a run-as role was specified, push it so that any calls made
        by this bean will have the runAsRole available for declarative
        security checks.
       */
-      SecurityActions.pushRunAsIdentity(runAsIdentity);
+      SecurityActions.pushRunAsIdentity(runAsIdentity); 
 
       try
       {
@@ -211,10 +257,41 @@
          SecurityActions.popRunAsIdentity(); 
          SecurityActions.popSubjectContext();
          //Clear the SecurityContext
-         SecurityActions.clearSecurityContext(appSecurityDomain);
+         SecurityActions.clearSecurityContext(appSecurityDomain); 
       }
    }
+  
+   /**
+    * Determine whether the caller is trusted such that the authentication checks
+    * can be bypassed
+    * TODO: Needs additional work wrt caller inter-vm run-as semantics,saml etc
+    * @param inv invocation
+    * @return
+    */
+   protected boolean isTrustedCaller(Invocation inv)
+   {
+      boolean trusted = false;
+      SecurityContext callerSC = getInvocationSecurityContext(inv);  
+      if(callerSC != null)
+      {
+         //authenticate the current principal
+         RunAsIdentity callerRunAsIdentity = getCallerRunAsIdentity(inv);
+         if(callerRunAsIdentity != null)
+         {
+            //Either has to be a in-vm call or the invocation has to be secure
+            Boolean intervm = (Boolean) inv.getAsIsPayload().get(InvocationKey.INTERVM);
+            trusted = intervm == null || intervm == Boolean.FALSE || inv.isSecure();
+         }
+      }
+      
+      return trusted;
+   }
    
+   private SecurityContext getInvocationSecurityContext(Invocation inv)
+   {
+      return (SecurityContext) inv.getAsIsPayload().get(InvocationKey.SECURITY_CONTEXT);
+   }
+   
    /** The EJB 2.0 declarative security algorithm:
    1. Authenticate the caller using the principal and credentials in the MethodInfocation
    2. Validate access to the method by checking the principal's roles against
@@ -226,7 +303,7 @@
      Principal principal = mi.getPrincipal();
      Object credential = mi.getCredential();
      boolean trace = log.isTraceEnabled();
-
+     
      // If there is not a security manager then there is no authentication required
      Method m = mi.getMethod();
      boolean containerMethod = m == null || m.equals(ejbTimeout);
@@ -241,10 +318,8 @@
      {
         throw new SecurityException("Role mapping manager has not been set");
      }
-
-     // authenticate the current principal
-     RunAsIdentity callerRunAsIdentity = SecurityActions.peekRunAsIdentity();
-     if (callerRunAsIdentity == null)
+     
+     if (!isTrustedCaller(mi))
      {
         // Check the security info from the method invocation
         Subject subject = new Subject();
@@ -255,20 +330,20 @@
               authenticationObserver.authenticationFailed();
            // Check for the security association exception
            Exception ex = SecurityActions.getContextException();
-           errorAudit(principal,m.getName(),ex);
+           audit(AuditLevel.ERROR,getContextMap(principal, m.getName()),ex); 
            if( ex != null )
               throw ex;
            // Else throw a generic SecurityException
            String msg = "Authentication exception, principal=" + principal;
            SecurityException e = new SecurityException(msg);
-           failureAudit(principal,m.getName());
+           audit(AuditLevel.FAILURE,getContextMap(principal, m.getName()),null); 
            throw e;
         }
         else
         {
            SecurityActions.pushSubjectContext(principal, credential, subject);
            establishSecurityContext(securityManager.getSecurityDomain(),principal, credential, subject);
-           successAudit(principal,m.getName());
+           audit(AuditLevel.SUCCESS,getContextMap(principal, m.getName()),null); 
            if (trace)
            {
               log.trace("Authenticated  principal=" + principal);
@@ -278,7 +353,17 @@
      else
      {
         // Duplicate the current subject context on the stack since
-        SecurityActions.dupSubjectContext();
+        SecurityActions.dupSubjectContext(); 
+        establishSecurityContext(securityManager.getSecurityDomain(),principal, credential, null);
+        
+        /**
+         * Since the RunAsIdentity has been populated via the SecurityContext by the
+         * proxy security interceptor, there is no need to duplicate it, as it will
+         * be available on the threadlocal securitycontext association
+         */
+        /*SecurityContext sc= SecurityContextAssociation.getSecurityContext();
+        if(sc != null)
+           SecurityContextAssociation.push(sc);*/
      } 
      
      Method ejbMethod = mi.getMethod();
@@ -291,7 +376,7 @@
      //Establish the deployment rolename-principalset custom mapping(if available)
      SecurityRolesAssociation.setSecurityRoles(this.deploymentRoles);
       
-     final HashMap map =  new HashMap();
+     final HashMap<String,Object> map =  new HashMap<String,Object>();
      map.put(ResourceKeys.EJB_NAME ,this.ejbName);
      map.put(ResourceKeys.EJB_METHOD,ejbMethod); 
      map.put(ResourceKeys.EJB_PRINCIPAL, mi.getPrincipal());
@@ -299,7 +384,7 @@
      map.put(ResourceKeys.EJB_CODESOURCE, ejbCS);
      map.put(ResourceKeys.CALLER_SUBJECT, caller);
      map.put(ResourceKeys.AUTHORIZATION_MANAGER,authorizationManager); 
-     map.put(ResourceKeys.RUNASIDENTITY, callerRunAsIdentity);
+     map.put(ResourceKeys.RUNASIDENTITY, getCallerRunAsIdentity(mi));
      map.put(ResourceKeys.EJB_METHODROLES, container.getMethodPermissions(ejbMethod, mi.getType()));  
      
      EJBResource ejbResource = new EJBResource(map); 
@@ -344,63 +429,66 @@
      Subject caller = null;
      try
      { 
-        SecurityActions.pushRunAsIdentity(runAsIdentity);
+       // SecurityActions.pushRunAsIdentity(runAsIdentity);
         caller = SecurityActions.getContextSubject();
      }
      finally
      { 
-        SecurityActions.popRunAsIdentity();
+        //SecurityActions.popRunAsIdentity();
      }   
      return caller;
   }
   
+  private RunAsIdentity getCallerRunAsIdentity(Invocation inv)
+  {
+     RunAsIdentity callerRAI = null;
+     SecurityContext callerSC = (SecurityContext) inv.getAsIsPayload().get(InvocationKey.SECURITY_CONTEXT); 
+     
+     if(callerSC != null)
+     { 
+        callerRAI = callerSC.getUtil().get(callerSC, RUNAS_IDENTITY_IDENTIFIER); 
+     }
+     return callerRAI;
+  }
+  
+  
+  
   //******************************************************
   //  Audit Methods
   //******************************************************
   private void audit(String level,
-        Map contextMap, Exception e)
+        Map<String,Object> contextMap, Exception e)
   { 
      contextMap.put("Source", getClass().getName());
-     String secDomain = securityManager.getSecurityDomain();
-     SecurityContext sc = SecurityActions.getSecurityContext(secDomain); 
-     AuditContext ac = sc != null ? sc.getAuditContext() :
-                         AuditManager.getAuditContext(secDomain); 
      AuditEvent ae = new AuditEvent(level);
      ae.setContextMap(contextMap);
      ae.setUnderlyingException(e);
-     ac.audit(ae);   
+     
+     String secDomain = securityManager.getSecurityDomain();
+     SecurityContext sc = SecurityActions.getSecurityContext(secDomain);
+     if(sc != null)
+     {
+        SecurityAuditManager sam = sc.getAuditManager();
+        sam.audit(ae);
+     }
+     else
+        AuditManager.getAuditContext(secDomain).audit(ae);   
   }
   
-  private void successAudit(Principal principal, String methodName)
-  { 
-     audit(AuditLevel.SUCCESS,getContextMap(principal, methodName),null);
-  } 
-  
-  private void failureAudit(Principal principal, String methodName)
-  { 
-     audit(AuditLevel.FAILURE,getContextMap(principal, methodName),null);
-  }
-  
-  private void errorAudit(Principal principal,
-        String methodName, Exception e)
-  { 
-     audit(AuditLevel.ERROR,getContextMap(principal, methodName),e);
-  }
-  
   private void authorizationAudit(String level, EJBResource resource, Exception e)
   {
      //Authorization Exception stacktrace is huge. Scale it down
      //as the original stack trace can be seen in server.log (if needed)
      String exceptionMessage = e != null ? e.getLocalizedMessage() : "";  
-     Map cmap = new HashMap();
+     Map<String,Object> cmap = new HashMap<String,Object>();
      cmap.putAll(resource.getMap());
      cmap.put("Exception:", exceptionMessage);
      audit(level,cmap,null);
   } 
   
-  private Map getContextMap(Principal principal, String methodName)
+  private Map<String,Object> getContextMap(Principal principal, String methodName)
   {
-     Map cmap = new HashMap();
+     Map<String,Object> cmap = new HashMap<String,Object>();
      cmap.put("principal", principal);
      cmap.put("method", methodName);
      return cmap;
@@ -410,12 +498,6 @@
   private void establishSecurityContext(String domain, Principal p, Object cred,
         Subject subject)
   {
-     JBossSecurityContext jsc = new JBossSecurityContext(domain);
-     SubjectInfo si =  jsc.new SubjectInfo();
-     si.setAuthenticatedSubject(subject);
-     si.setAuthenticationCredential(cred);
-     si.setAuthenticationPrincipal(p);
-     jsc.setSubjectInfo(si); 
-     SecurityActions.setSecurityContext(jsc, domain);
-  } 
+     SecurityActions.createAndSetSecurityContext(p, cred, domain,subject); 
+  }  
 }

Modified: trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -52,17 +52,23 @@
 import org.jboss.ejb.Container;
 import org.jboss.ejb.EJBProxyFactoryContainer;
 import org.jboss.ejb.LocalProxyFactory;
+import org.jboss.invocation.InvocationKey;
 import org.jboss.invocation.InvocationType;
 import org.jboss.invocation.MarshalledInvocation;
 import org.jboss.invocation.LocalEJBInvocation;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.BeanMetaData;
 import org.jboss.naming.Util;
+import org.jboss.security.RunAsIdentity;
 import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext; 
+import org.jboss.security.plugins.SecurityContextAssociation; 
 import org.jboss.util.NestedRuntimeException;
 import org.jboss.tm.TransactionLocal;
 
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
 
+
 /**
  * The LocalProxyFactory implementation that handles local ejb interface
  * proxies.
@@ -71,6 +77,7 @@
  * @author <a href="mailto:scott.stark at jboss.org">Scott Stark</a>
  * @author <a href="mailto:dain at daingroup.com">Dain Sundstrom</a>
  * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author Anil.Saldhana at redhat.com
  * $Revision$
  */
 public class BaseLocalProxyFactory implements LocalProxyFactory
@@ -346,7 +353,10 @@
       }
       container.pushENC();
 
-      SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+      SecurityActions sa = SecurityActions.UTIL.getSecurityActions(); 
+      SecurityContext existingSC = sa.getSecurityContext();
+      RunAsIdentity cachedRAI = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER);
+      
       try
       {
          LocalEJBInvocation invocation = new LocalEJBInvocation(null,
@@ -357,6 +367,9 @@
             sa.getCredential());
          invocation.setType(InvocationType.LOCALHOME);
 
+         //Just place the current security context on the invocation 
+         if(existingSC != null)
+           invocation.getAsIsPayload().put(InvocationKey.SECURITY_CONTEXT, existingSC);
          return container.invoke(invocation);
       }
       catch(AccessException ae)
@@ -382,6 +395,11 @@
          {
             TCLAction.UTIL.setContextClassLoader(oldCl);
          }
+         if(cachedRAI != null)
+         {
+            existingSC = sa.getSecurityContext();
+            existingSC.getUtil().set(existingSC, RUNAS_IDENTITY_IDENTIFIER, cachedRAI);
+         }
       }
    }
 
@@ -419,7 +437,10 @@
       }
       container.pushENC();
 
-      SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+      SecurityActions sa = SecurityActions.UTIL.getSecurityActions(); 
+      SecurityContext existingSC = sa.getSecurityContext();
+      RunAsIdentity cachedRAI = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER);
+      
       try
       {
          LocalEJBInvocation invocation = new LocalEJBInvocation(id,
@@ -429,7 +450,11 @@
             sa.getPrincipal(),
             sa.getCredential());
          invocation.setType(InvocationType.LOCAL);
-
+         
+         //Just place the current security context on the invocation 
+         if(existingSC != null)
+           invocation.getAsIsPayload().put(InvocationKey.SECURITY_CONTEXT, existingSC);
+         
          return container.invoke(invocation);
       }
       catch(AccessException ae)
@@ -455,6 +480,11 @@
          {
             TCLAction.UTIL.setContextClassLoader(oldCl);
          }
+         if(cachedRAI != null)
+         {
+            existingSC = sa.getSecurityContext();
+            existingSC.getUtil().set(existingSC, RUNAS_IDENTITY_IDENTIFIER, cachedRAI);
+         }
       }
    }
 
@@ -534,6 +564,11 @@
          {
             return SecurityAssociation.getCredential();
          }
+         
+         public SecurityContext getSecurityContext()
+         {
+            return SecurityContextAssociation.getSecurityContext(); 
+         }
       };
 
       SecurityActions PRIVILEGED = new SecurityActions()
@@ -563,11 +598,23 @@
          {
             return AccessController.doPrivileged(getCredentialAction);
          }
+         
+         public SecurityContext getSecurityContext()
+         {
+            return (SecurityContext)AccessController.doPrivileged(
+                  new PrivilegedAction(){
+
+                     public Object run()
+                     { 
+                        return SecurityContextAssociation.getSecurityContext();
+                     }});
+         }
       };
 
       Principal getPrincipal();
 
       Object getCredential();
+      SecurityContext getSecurityContext(); 
    }
 
    interface TCLAction

Modified: trunk/server/src/main/org/jboss/invocation/Invocation.java
===================================================================
--- trunk/server/src/main/org/jboss/invocation/Invocation.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/invocation/Invocation.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -22,10 +22,6 @@
 package org.jboss.invocation;
 
 import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ByteArrayInputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.security.Principal;
@@ -42,17 +38,18 @@
  *    <em>Invocation</em> object that can interpret the data in it. 
  * 
  * <p>Essentially we can carry ANYTHING from the client to the server, we keep
- *    a series of of predifined variables and method calls to get at the 
+ *    a series of of predefined variables and method calls to get at the 
  *    pointers.  But really it is just  a repository of objects. 
  *
  * @author  <a href="mailto:marc at jboss.org">Marc Fleury</a>
  * @author  <a href="mailto:christoph.jung at infor.de">Christoph G. Jung</a>
+ * @author Anil.Saldhana at jboss.org
  * @version $Revision$
  */
 public class Invocation
 {
    /** The signature of the invoke() method */
-   public static final String[] INVOKE_SIGNATURE = { "org.jboss.invocation.Invocation" };
+   public static final String[] INVOKE_SIGNATURE = { "org.jboss.invocation.Invocation" }; 
 
    // The payload is a repository of everything associated with the invocation
    // It is information that will need to travel 
@@ -306,10 +303,7 @@
    {
       return this.args;
    }
-   
-   /**
-    * marcf: SCOTT WARNING! I removed the "setPrincipal" that was called here
-    */
+
    public InvocationContext getInvocationContext()
    {
       return invocationContext;
@@ -329,6 +323,16 @@
    {
       return getTransientPayload().get(InvocationKey.ENTERPRISE_CONTEXT);
    }
+   
+   /**
+    * Set whether the invocation is secure or not
+    * @param secure boolean value
+    */
+   public void setSecure(Boolean secure)
+   {
+      this.getAsIsPayload().put(InvocationKey.SECURE, secure);   
+   }
+   
 
    public Map getTransientPayload()
    {
@@ -369,4 +373,13 @@
       InvocationType type = getType();
       return (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
    }
+   
+   /**
+    * Determine whether the invocation arrived on a secure channel
+    * @return true invocation is secure
+    */
+   public Boolean isSecure()
+   {
+      return (Boolean) this.getAsIsPayload().get(InvocationKey.SECURE);
+   }
 }

Modified: trunk/server/src/main/org/jboss/invocation/InvocationKey.java
===================================================================
--- trunk/server/src/main/org/jboss/invocation/InvocationKey.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/invocation/InvocationKey.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -42,7 +42,7 @@
     * new key enum value you must assign it an ordinal value of the current
     * MAX_KEY_ID+1 and update the MAX_KEY_ID value.
     */
-   private static final int MAX_KEY_ID = 18;
+   private static final int MAX_KEY_ID = 21;
 
    /** The array of InvocationKey indexed by ordinal value of the key */
    private static final InvocationKey[] values = new InvocationKey[MAX_KEY_ID+1];
@@ -144,10 +144,29 @@
    public final static InvocationKey SOAP_MESSAGE =
          new InvocationKey("SOAP_MESSAGE", 16);
 
-   /** The JAAC context id associated with the invocatio */
+   /** The JAAC context id associated with the invocation */
    public final static InvocationKey JACC_CONTEXT_ID =
          new InvocationKey("JACC_CONTEXT_ID", 17);
 
+   /**
+    * The Security Context associated with the invocation
+    */
+   public final static InvocationKey SECURITY_CONTEXT =
+      new InvocationKey("SECURITY_CONTEXT", 18);
+   
+   /**
+    * Indicate whether the invocation is secure
+    */
+   public final static InvocationKey SECURE =
+      new InvocationKey("SECURE", 19);
+   
+   /**
+    * Indicate whether an inter-vm invocation
+    */
+   public final static InvocationKey INTERVM =
+      new InvocationKey("INTERVM", 20);
+   
+   
    /** The key enum symbolic value */
    private final transient String name;
    /** The persistent integer representation of the key enum */

Modified: trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -236,6 +236,9 @@
     */
    protected Object invokeInvoker(Invocation invocation) throws Exception
    {
+      //Specify that it is inter-vm on the invocation
+      invocation.getAsIsPayload().put(InvocationKey.INTERVM, Boolean.TRUE);
+      
       InvocationContext ctx = invocation.getInvocationContext();
       Invoker invoker = ctx.getInvoker();
       return invoker.invoke(invocation);

Modified: trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -29,7 +29,7 @@
 import org.jboss.mx.interceptor.AbstractInterceptor;
 import org.jboss.mx.interceptor.Interceptor;
 import org.jboss.security.SubjectSecurityManager;
-import org.jboss.security.SecurityContext.SubjectInfo;
+import org.jboss.security.SubjectInfo;
 import org.jboss.security.plugins.JBossSecurityContext;
 
 
@@ -118,7 +118,7 @@
          Subject subject)
    {
       JBossSecurityContext jsc = new JBossSecurityContext(domain);
-      SubjectInfo si =  jsc.new SubjectInfo();
+      SubjectInfo si = new SubjectInfo();
       si.setAuthenticatedSubject(subject);
       si.setAuthenticationCredential(cred);
       si.setAuthenticationPrincipal(p);

Added: trunk/server/src/main/org/jboss/proxy/SecurityActions.java
===================================================================
--- trunk/server/src/main/org/jboss/proxy/SecurityActions.java	                        (rev 0)
+++ trunk/server/src/main/org/jboss/proxy/SecurityActions.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -0,0 +1,191 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.proxy;
+
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import org.jboss.security.RunAsIdentity;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.plugins.SecurityContextAssociation;
+import org.jboss.security.plugins.SecurityContextFactory;
+
+//$Id$
+
+/**
+ * Interface defining the Privileged Blocks 
+ *  @author <a href="mailto:Anil.Saldhana at jboss.org">Anil Saldhana</a>
+ *  @since  Mar 5, 2007 
+ *  @version $Revision$
+ */
+interface SecurityActions
+{ 
+   class UTIL
+   {
+      static SecurityActions getSecurityActions()
+      {
+         return System.getSecurityManager() == null ? NON_PRIVILEGED : PRIVILEGED;
+      }
+   }
+
+   SecurityActions NON_PRIVILEGED = new SecurityActions()
+   {
+      public Principal getPrincipal()
+      {
+         return SecurityAssociation.getPrincipal();
+      }
+
+      public Object getCredential()
+      {
+         return SecurityAssociation.getCredential();
+      }
+      
+      public RunAsIdentity getCallerRunAsIdentity()
+      {
+         RunAsIdentity rai = null;
+         //Pluck the run-as identity from the existing SC if any
+         SecurityContext existingSC = getSecurityContext();
+         if(existingSC != null)
+         { 
+            rai = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER); 
+         }
+         return rai;   
+      }
+
+      public SecurityContext getSecurityContext()
+      {
+         return SecurityContextAssociation.getSecurityContext();
+      }
+
+      public void setSecurityContext(SecurityContext sc)
+      {
+         SecurityContextAssociation.setSecurityContext(sc);
+      }
+      
+      public SecurityContext createSecurityContext(Principal p, Object cred, 
+            String sdomain)
+      {
+         return SecurityContextFactory.createSecurityContext(p,cred, null, sdomain);
+      }
+   };
+
+   SecurityActions PRIVILEGED = new SecurityActions()
+   {
+      private final PrivilegedAction getPrincipalAction = new PrivilegedAction()
+      {
+         public Object run()
+         {
+            return SecurityAssociation.getPrincipal();
+         }
+      };
+
+      private final PrivilegedAction getCredentialAction = new PrivilegedAction()
+      {
+         public Object run()
+         {
+            return SecurityAssociation.getCredential();
+         }
+      };
+
+      private final PrivilegedAction getSecurityContextAction = new PrivilegedAction()
+      {
+         public Object run()
+         {
+            return SecurityContextAssociation.getSecurityContext();
+         }
+      };  
+
+      public Principal getPrincipal()
+      {
+         return (Principal)AccessController.doPrivileged(getPrincipalAction);
+      }
+
+      public Object getCredential()
+      {
+         return AccessController.doPrivileged(getCredentialAction);
+      }
+      
+      public RunAsIdentity getCallerRunAsIdentity()
+      {
+         return (RunAsIdentity)AccessController.doPrivileged(new PrivilegedAction(){
+
+            public Object run()
+            {
+               RunAsIdentity rai = null;
+               //Pluck the run-as identity from the existing SC if any
+               SecurityContext existingSC = getSecurityContext();
+               if(existingSC != null)
+               { 
+                  rai = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER); 
+               }
+               return rai;  
+            }});
+         
+      }
+
+      public SecurityContext getSecurityContext()
+      {
+         return (SecurityContext) AccessController.doPrivileged(getSecurityContextAction);
+      }
+
+      public void setSecurityContext(final SecurityContext sc)
+      {
+         AccessController.doPrivileged(new PrivilegedAction(){
+
+            public Object run()
+            {
+               SecurityContextAssociation.setSecurityContext(sc);
+               return null;
+            }}); 
+      }
+      
+      public SecurityContext createSecurityContext(final Principal p, final Object cred, 
+            final String sdomain)
+      {
+         return (SecurityContext) AccessController.doPrivileged(new PrivilegedAction(){
+
+            public Object run()
+            {
+               return SecurityContextFactory.createSecurityContext(p,cred, null, sdomain);
+            }
+            
+         }); 
+      }
+   };
+
+   Principal getPrincipal();
+
+   Object getCredential();
+   
+   RunAsIdentity getCallerRunAsIdentity();
+
+   SecurityContext createSecurityContext( Principal p,  Object cred, 
+         String sdomain);
+   
+   SecurityContext getSecurityContext(); 
+   
+   void setSecurityContext(SecurityContext sc);  
+}

Modified: trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java	2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java	2007-04-11 16:30:46 UTC (rev 62258)
@@ -21,17 +21,20 @@
 */
 package org.jboss.proxy;
 
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
+import java.security.Principal; 
 
 import org.jboss.invocation.Invocation;
-import org.jboss.security.SecurityAssociation;
+import org.jboss.invocation.InvocationKey;
+import org.jboss.security.RunAsIdentity; 
+import org.jboss.security.SecurityContext;  
 
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER; 
+
 /**
 * The client-side proxy for an EJB Home object.
 *      
 * @author <a href="mailto:marc.fleury at jboss.org">Marc Fleury</a>
+* @author Anil.Saldhana at redhat.com
 * @version $Revision$
 */
 public class SecurityInterceptor
@@ -39,7 +42,7 @@
 {
    /** Serial Version Identifier. @since 1.4.2.1 */
    private static final long serialVersionUID = -4206940878404525061L;
-
+   
    /**
    * No-argument constructor for externalization.
    */
@@ -66,64 +69,47 @@
       {
          invocation.setCredential(credential);
       }
-
-      return getNext().invoke(invocation);
-   }
-
-   interface SecurityActions
-   {
-      class UTIL
+ 
+      RunAsIdentity callerRAI = sa.getCallerRunAsIdentity();
+      SecurityContext newSc = createSecurityContext(invocation);
+      //Push the caller run-as identity onto the security context 
+      if(callerRAI != null)
       {
-         static SecurityActions getSecurityActions()
-         {
-            return System.getSecurityManager() == null ? NON_PRIVILEGED : PRIVILEGED;
-         }
+         newSc.getUtil().set(newSc, RUNAS_IDENTITY_IDENTIFIER, callerRAI);
       }
-
-      SecurityActions NON_PRIVILEGED = new SecurityActions()
+      /**
+       * Push the security context on the invocation
+       */
+      invocation.getAsIsPayload().put(InvocationKey.SECURITY_CONTEXT, newSc);
+      
+      try
+      { 
+         return getNext().invoke(invocation); 
+      }
+      finally
       {
-         public Principal getPrincipal()
-         {
-            return SecurityAssociation.getPrincipal();
-         }
-
-         public Object getCredential()
-         {
-            return SecurityAssociation.getCredential();
-         }
-      };
-
-      SecurityActions PRIVILEGED = new SecurityActions()
-      {
-         private final PrivilegedAction getPrincipalAction = new PrivilegedAction()
-         {
-            public Object run()
-            {
-               return SecurityAssociation.getPrincipal();
-            }
-         };
-
-         private final PrivilegedAction getCredentialAction = new PrivilegedAction()
-         {
-            public Object run()
-            {
-               return SecurityAssociation.getCredential();
-            }
-         };
-
-         public Principal getPrincipal()
-         {
-            return (Principal)AccessController.doPrivileged(getPrincipalAction);
-         }
-
-         public Object getCredential()
-         {
-            return AccessController.doPrivileged(getCredentialAction);
-         }
-      };
-
-      Principal getPrincipal();
-
-      Object getCredential();
+         //Set the cached original RAI on the return path
+         SecurityContext existingSC = sa.getSecurityContext();
+         if(existingSC != null)
+            existingSC.getUtil().set(existingSC, RUNAS_IDENTITY_IDENTIFIER, callerRAI); 
+      }
    }
+   
+   /**
+    * Return loaded Security Context to be passed on the invocation
+    * @param invocation invocation instance
+    * @return
+    */
+   private SecurityContext createSecurityContext(Invocation invocation)
+   { 
+      SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+
+      //There may be principal set on the invocation
+      Principal p = invocation.getPrincipal();
+      Object cred = invocation.getCredential(); 
+      
+      //Create a new SecurityContext
+      //TODO: Need to get SecurityDomain name??
+      return sa.createSecurityContext(p,cred, "CLIENT_PROXY");
+   } 
 }




More information about the jboss-cvs-commits mailing list