[jboss-cvs] JBossAS SVN: r63219 - in trunk/ejb3/src: main/org/jboss/ejb3 and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon May 28 03:54:46 EDT 2007


Author: wolfc
Date: 2007-05-28 03:54:46 -0400 (Mon, 28 May 2007)
New Revision: 63219

Modified:
   trunk/ejb3/src/main/org/jboss/annotation/security/SecurityDomainImpl.java
   trunk/ejb3/src/main/org/jboss/ejb3/Container.java
   trunk/ejb3/src/main/org/jboss/ejb3/EJBContainer.java
   trunk/ejb3/src/main/org/jboss/ejb3/Ejb3DescriptorHandler.java
   trunk/ejb3/src/main/org/jboss/ejb3/security/AuthenticationInterceptorFactory.java
   trunk/ejb3/src/main/org/jboss/ejb3/security/Ejb3AuthenticationInterceptor.java
   trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptor.java
   trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptorFactory.java
   trunk/ejb3/src/main/org/jboss/ejb3/security/JaccHelper.java
   trunk/ejb3/src/test/org/jboss/ejb3/test/ejbthree973/unit/AnonymousCallerPrincipalTestCase.java
Log:
EJBTHREE-973: allow security domain with only an unauthenticated principal

Modified: trunk/ejb3/src/main/org/jboss/annotation/security/SecurityDomainImpl.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/annotation/security/SecurityDomainImpl.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/annotation/security/SecurityDomainImpl.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -21,6 +21,8 @@
  */
 package org.jboss.annotation.security;
 
+import java.lang.annotation.Annotation;
+
 import org.jboss.annotation.security.SecurityDomain;
 
 /**
@@ -33,7 +35,12 @@
 {
    private String value;
    private String unauthenticatedPrincipal = null;
-  
+   
+   public SecurityDomainImpl()
+   {
+      this("");
+   }
+   
    public SecurityDomainImpl(String value)
    {
       this.value = value;
@@ -54,7 +61,7 @@
       this.unauthenticatedPrincipal = unauthenticatedPrincipal;
    }
 
-   public Class annotationType()
+   public Class<? extends Annotation> annotationType()
    {
       return org.jboss.annotation.security.SecurityDomain.class;
    }

Modified: trunk/ejb3/src/main/org/jboss/ejb3/Container.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/Container.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/Container.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -31,6 +31,10 @@
 
 /**
  * Comment
+ * 
+ * A container is optionally associated with a security manager. If it is
+ * the container is running in secured mode, if not the container is running
+ * in unchecked mode.
  *
  * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
  * @version $Revision$
@@ -87,4 +91,12 @@
    DependencyPolicy getDependencyPolicy();
    
    InvocationStatistics getInvokeStats();
+   
+   /**
+    * Get the security manager associated with a container.
+    * 
+    * @param    type   the type to cast to
+    * @return   the security manager or null if there is no manager associated
+    */
+   <T> T getSecurityManager(Class<T> type);
 }

Modified: trunk/ejb3/src/main/org/jboss/ejb3/EJBContainer.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/EJBContainer.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/EJBContainer.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -53,6 +53,7 @@
 
 import org.jboss.annotation.ejb.Clustered;
 import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.annotation.security.SecurityDomain;
 import org.jboss.aop.AspectManager;
 import org.jboss.aop.ClassContainer;
 import org.jboss.aop.MethodInfo;
@@ -68,6 +69,7 @@
 import org.jboss.ejb3.metamodel.AssemblyDescriptor;
 import org.jboss.ejb3.metamodel.EnterpriseBean;
 import org.jboss.ejb3.security.JaccHelper;
+import org.jboss.ejb3.security.SecurityDomainManager;
 import org.jboss.ejb3.statistics.InvocationStatistics;
 import org.jboss.ejb3.tx.UserTransactionImpl;
 import org.jboss.iiop.CorbaORBService;
@@ -634,6 +636,25 @@
       super.cleanup();
    }
 
+   @SuppressWarnings("unchecked")
+   public <T> T getSecurityManager(Class<T> type)
+   {
+      try
+      {
+         InitialContext ctx = getInitialContext();
+         SecurityDomain securityAnnotation = (SecurityDomain) resolveAnnotation(SecurityDomain.class);
+         if (securityAnnotation != null && securityAnnotation.value().length() > 0)
+         {
+            return (T) SecurityDomainManager.getSecurityManager(securityAnnotation.value(),ctx);
+         }
+         return null;
+      }
+      catch (NamingException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+   
    protected void initializePool() throws Exception
    {
       PoolClass poolClass = (PoolClass) resolveAnnotation(PoolClass.class);

Modified: trunk/ejb3/src/main/org/jboss/ejb3/Ejb3DescriptorHandler.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/Ejb3DescriptorHandler.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/Ejb3DescriptorHandler.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -945,15 +945,19 @@
       {
          SecurityDomain annotation = (SecurityDomain) ejbClass
                .getAnnotation(SecurityDomain.class);
+         SecurityDomainImpl override;
          if (annotation != null)
          {
-            SecurityDomainImpl override = new SecurityDomainImpl(annotation
-                  .value());
+            override = new SecurityDomainImpl(annotation.value());
             override.setUnauthenticatedPrincipal(dd
                   .getUnauthenticatedPrincipal());
-
-            addClassAnnotation(container, override.annotationType(), override);
          }
+         else
+         {
+            override = new SecurityDomainImpl();
+            override.setUnauthenticatedPrincipal(dd.getUnauthenticatedPrincipal());
+         }
+         addClassAnnotation(container, override.annotationType(), override);
       }
    }
 

Modified: trunk/ejb3/src/main/org/jboss/ejb3/security/AuthenticationInterceptorFactory.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/security/AuthenticationInterceptorFactory.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/security/AuthenticationInterceptorFactory.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -21,15 +21,12 @@
  */
 package org.jboss.ejb3.security;
 
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.jboss.annotation.security.SecurityDomain;
 import org.jboss.aop.Advisor;
 import org.jboss.aop.InstanceAdvisor;
 import org.jboss.aop.advice.AspectFactory;
 import org.jboss.aop.joinpoint.Joinpoint;
-import org.jboss.security.AuthenticationManager;
 import org.jboss.ejb3.Container;
+import org.jboss.security.AuthenticationManager;
 
 public class AuthenticationInterceptorFactory implements AspectFactory
 {
@@ -40,22 +37,8 @@
 
    public Object createPerClass(Advisor advisor)
    {
-      Object domain = null;
       Container container = (Container)advisor;
-      try
-      {
-         InitialContext ctx = container.getInitialContext();
-         SecurityDomain securityAnnotation = (SecurityDomain) advisor.resolveAnnotation(SecurityDomain.class);
-         if (securityAnnotation != null)
-         {
-            domain = SecurityDomainManager.getSecurityManager(securityAnnotation.value(),ctx);
-         }
-      }
-      catch (NamingException e)
-      {
-         throw new RuntimeException(e);
-      }
-      AuthenticationManager manager = (AuthenticationManager) domain;
+      AuthenticationManager manager = container.getSecurityManager(AuthenticationManager.class);
       return new Ejb3AuthenticationInterceptor(manager, container);
    }
 

Modified: trunk/ejb3/src/main/org/jboss/ejb3/security/Ejb3AuthenticationInterceptor.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/security/Ejb3AuthenticationInterceptor.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/security/Ejb3AuthenticationInterceptor.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -22,24 +22,27 @@
 package org.jboss.ejb3.security;
 
 import java.security.GeneralSecurityException;
-import java.security.Principal; 
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.ejb.EJBAccessException;
+import javax.security.auth.Subject;
 
+import org.jboss.annotation.security.SecurityDomain;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.aspects.security.AuthenticationInterceptor;
 import org.jboss.ejb3.Container;
 import org.jboss.ejb3.EJBContainer;
 import org.jboss.logging.Logger;
-
-import org.jboss.annotation.security.SecurityDomain;
-import org.jboss.aop.joinpoint.MethodInvocation;
-
-import org.jboss.aspects.security.AuthenticationInterceptor;
-import org.jboss.aspects.security.SecurityContext;
 import org.jboss.security.AuthenticationManager;
-import org.jboss.security.RealmMapping; 
+import org.jboss.security.RealmMapping;
 import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
 import org.jboss.security.SecurityRolesAssociation;
 import org.jboss.security.SimplePrincipal;
+import org.jboss.security.plugins.SecurityContextAssociation;
+import org.jboss.security.plugins.SecurityContextFactory;
 
 /**
  * Authentication Interceptor
@@ -54,12 +57,37 @@
 
    private EJBContainer container;
    protected RealmMapping realmMapping;
+   
+   /**
+    * AuthenticationInterceptor which bypasses the AuthenticationManager, so
+    * an unauthenticated principal won't be authenticated against an AuthenticationManager.
+    */
+   private AuthenticationInterceptor unauthenticatedAuthenticationInterceptor;
 
-   public Ejb3AuthenticationInterceptor(AuthenticationManager manager, Container container)
+   public Ejb3AuthenticationInterceptor(final AuthenticationManager manager, Container container)
    {
       super(manager);
       this.container = (EJBContainer)container;
       this.realmMapping = (RealmMapping)manager;
+      // TODO: can be optimized to only instantiate when securityDomain has an unauthenticatedPrincipal
+      this.unauthenticatedAuthenticationInterceptor = new AuthenticationInterceptor(null)
+      {
+         @Override
+         protected void authenticate(Invocation invocation) throws Exception
+         {
+            super.authenticate(invocation);
+            
+            // if we have a manager mimic run as stuff, so we end up with a Subject for JACC
+            if(manager != null)
+            {
+               Principal principal = (Principal)invocation.getMetaData("security", "principal");
+               Subject subject = new Subject();
+               String securityDomain = manager.getSecurityDomain();
+               SecurityContext sc = SecurityContextFactory.createSecurityContext(principal, null, subject, securityDomain);
+               SecurityContextAssociation.setSecurityContext(sc);
+            }
+         }
+      };
    }
 
    protected void handleGeneralSecurityException(GeneralSecurityException gse)
@@ -70,7 +98,6 @@
 
    public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable
    {
-      MethodInvocation mi = (MethodInvocation)invocation;
       SecurityDomain domain = (SecurityDomain)container.resolveAnnotation(SecurityDomain.class);
       
       if (domain != null && domain.unauthenticatedPrincipal() != null && domain.unauthenticatedPrincipal().length() != 0)
@@ -78,23 +105,22 @@
          Principal principal = (Principal)invocation.getMetaData("security", "principal");
          if (principal == null)
             principal = SecurityAssociation.getPrincipal();
-           
+         
          if (principal == null)
          {
-            invocation.getMetaData().addMetaData("security", "principal", new SimplePrincipal(domain.unauthenticatedPrincipal()));
+            // we don't have a principal, but we do have an unauthenticatedPrincipal we can use
+            principal = new TrustedPrincipal(domain.unauthenticatedPrincipal());
             
-            Object oldDomain = SecurityContext.getCurrentDomain().get();
-            
-            try
-            {
-               SecurityContext.getCurrentDomain().set(authenticationManager);
-               return invocation.invokeNext();
-            }
-            finally
-            {
-               SecurityContext.getCurrentDomain().set(oldDomain);
-            }
+            // this will be picked up by the AuthenticationInterceptor
+            invocation.getMetaData().addMetaData("security", "principal", principal);
          }
+         
+         // Either we got it from an earlier pass or we just instantiated it
+         if(principal != null && principal instanceof TrustedPrincipal)
+         {
+            // call an AuthenticationInterceptor which doesn't authenticate
+            return unauthenticatedAuthenticationInterceptor.invoke(invocation);
+         }
       }
       try
       {  
@@ -109,5 +135,15 @@
       { 
          SecurityRolesAssociation.setSecurityRoles(null);
       }
-   } 
+   }
+   
+   class TrustedPrincipal extends SimplePrincipal
+   {
+      private static final long serialVersionUID = 1L;
+
+      public TrustedPrincipal(String name)
+      {
+         super(name);
+      }
+   }
 }

Modified: trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptor.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptor.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptor.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -28,8 +28,10 @@
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.MethodInvocation;
 import org.jboss.aspects.remoting.InvokeRemoteInterceptor;
+import org.jboss.logging.Logger;
 import org.jboss.remoting.InvokerLocator;
 import org.jboss.security.RealmMapping;
+import org.jboss.security.jacc.DelegatingPolicy;
 
 
 /**
@@ -40,6 +42,8 @@
  */
 public class JaccAuthorizationInterceptor implements Interceptor
 {
+   private static final Logger log = Logger.getLogger(JaccAuthorizationInterceptor.class);
+   
    public static final String JACC = "JACC";
    public static final String CTX = "ctx";
 
@@ -84,6 +88,8 @@
       String contextID = (String) mi.getMetaData(JACC, CTX);
       SecurityActions.setContextID(contextID);
       
+      if(log.isTraceEnabled())
+         log.trace("permissions: " + DelegatingPolicy.getInstance().getPermissions(ejbCS));
       
       //EJBArgsPolicyContextHandler.setArgs(mi.getArguments());
 

Modified: trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptorFactory.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptorFactory.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/security/JaccAuthorizationInterceptorFactory.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -24,19 +24,13 @@
 
 import java.security.CodeSource;
 
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.jboss.annotation.security.SecurityDomain;
 import org.jboss.aop.Advisor;
 import org.jboss.aop.InstanceAdvisor;
 import org.jboss.aop.advice.AspectFactory;
 import org.jboss.aop.joinpoint.Joinpoint;
 import org.jboss.ejb3.Container;
 import org.jboss.ejb3.EJBContainer;
-import org.jboss.security.AuthenticationManager;
 import org.jboss.security.RealmMapping;
-import org.jboss.security.SubjectSecurityManager;
 
 /**
  * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
@@ -91,24 +85,10 @@
       return getClass().getName();
    }
    
-   public RealmMapping getSecurityManager(Advisor advisor)
+   protected RealmMapping getSecurityManager(Advisor advisor)
    {
-      Object domain = null;
-      Container container = (Container)advisor;
-      try
-      {
-         InitialContext ctx = container.getInitialContext();
-         SecurityDomain securityAnnotation = (SecurityDomain) advisor.resolveAnnotation(SecurityDomain.class);
-         if (securityAnnotation != null)
-         {
-            domain = SecurityDomainManager.getSecurityManager(securityAnnotation.value(),ctx);
-         }
-      }
-      catch (NamingException e)
-      {
-         throw new RuntimeException(e);
-      }
-      return (RealmMapping) domain;
+      Container container = (Container) advisor;
+      return container.getSecurityManager(RealmMapping.class);
    }
 }
 

Modified: trunk/ejb3/src/main/org/jboss/ejb3/security/JaccHelper.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/security/JaccHelper.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/main/org/jboss/ejb3/security/JaccHelper.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -99,6 +99,7 @@
    {
       //TODO: How do we link this with the parent PC?
       pc.commit(); 
+      log.trace("JACC Policy Configuration for deployment unit has been put in service");
    }
    
    public static void putJaccInService(PolicyConfiguration pc, DeploymentInfo di) throws Exception
@@ -184,15 +185,8 @@
       
       //Am I iterating over the right thing here? Should I be using the stuff from 
       //Advisor.methodInterceptors instead?
-      Method[] methods = container.getBeanClass().getDeclaredMethods();
-      for (int i = 0; i < methods.length; i++)
+      for(Method m : container.getBeanClass().getMethods())
       {
-         Method m = methods[i];
-         if (!Modifier.isPublic(m.getModifiers()))
-         {
-            continue;
-         }
-
          EJBMethodPermission permission = new EJBMethodPermission(ejbName, null, m);
          log.trace("Creating permission: " + permission);
 
@@ -327,9 +321,16 @@
             }*/
             //Get the current roles from the Authorization Manager
             Principal callerP = SecurityActions.getCallerPrincipal();
-            Set principalSet = realmMapping.getUserRoles(callerP);
-            principals = new Principal[principalSet.size()];
-            principalSet.toArray(principals);
+            Set<Principal> principalSet = realmMapping.getUserRoles(callerP);
+            if(principalSet == null)
+            {
+               principals = new Principal[0];
+            }
+            else
+            {
+               principals = new Principal[principalSet.size()];
+               principalSet.toArray(principals);
+            }
          } 
          
          ProtectionDomain pd = new ProtectionDomain(ejbCS, null, null, principals);

Modified: trunk/ejb3/src/test/org/jboss/ejb3/test/ejbthree973/unit/AnonymousCallerPrincipalTestCase.java
===================================================================
--- trunk/ejb3/src/test/org/jboss/ejb3/test/ejbthree973/unit/AnonymousCallerPrincipalTestCase.java	2007-05-28 07:34:28 UTC (rev 63218)
+++ trunk/ejb3/src/test/org/jboss/ejb3/test/ejbthree973/unit/AnonymousCallerPrincipalTestCase.java	2007-05-28 07:54:46 UTC (rev 63219)
@@ -24,6 +24,8 @@
 import junit.framework.Test;
 
 import org.jboss.ejb3.test.ejbthree973.WhoAmI;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SimplePrincipal;
 import org.jboss.test.JBossTestCase;
 
 /**
@@ -31,7 +33,7 @@
  * a security domain.
  *
  * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
+ * @version $Revision$
  */
 public class AnonymousCallerPrincipalTestCase extends JBossTestCase
 {
@@ -46,7 +48,7 @@
       return (WhoAmI) getInitialContext().lookup("WhoAmIBean/remote");
    }
    
-   public void testPrincipal() throws Exception
+   public void testAnonymous() throws Exception
    {
       WhoAmI bean = lookupBean();
       String actual = bean.getCallerPrincipal();
@@ -54,6 +56,15 @@
       assertEquals("anonymous", actual);
    }
    
+   public void testAnybody() throws Exception
+   {
+      SecurityAssociation.setPrincipal(new SimplePrincipal("anybody"));
+      WhoAmI bean = lookupBean();
+      String actual = bean.getCallerPrincipal();
+      // "anonymous" is defined in the @SecurityDomain on WhoAmIBean
+      assertEquals("anonymous", actual);
+   }
+   
    public static Test suite() throws Exception
    {
       return getDeploySetup(AnonymousCallerPrincipalTestCase.class, "ejbthree973.jar");




More information about the jboss-cvs-commits mailing list