FileDocCategorySizeDatePackage
JaccHelper.javaAPI DocJBoss 4.2.112775Fri Jul 13 20:53:52 BST 2007org.jboss.ejb3.security

JaccHelper

public class JaccHelper extends Object
JACC Helper class that created permissions as well as done the checks
author
Kabir Khan
author
Anil.Saldhana@jboss.com
version
$Revision$

Fields Summary
static Logger
log
Constructors Summary
Methods Summary
private static voidaddJaccContextToContainer(java.lang.String jaccContextId, org.jboss.ejb3.EJBContainer container)

      SimpleClassMetaDataLoader loader = SimpleClassMetaDataLoader.singleton;
      String name = container.getBeanClassName();
      SimpleClassMetaDataBinding jaccCtx =
              new SimpleClassMetaDataBinding(loader, name, JaccAuthorizationInterceptor.JACC, container.getBeanClassName());

      jaccCtx.addDefaultMetaData(JaccAuthorizationInterceptor.JACC,
                                 JaccAuthorizationInterceptor.CTX, jaccContextId);

      container.addClassMetaData(jaccCtx);
   
private static voidaddPermissions(org.jboss.ejb3.EJBContainer container, javax.security.jacc.PolicyConfiguration pc)

      SecurityDomain sd = (SecurityDomain) container.resolveAnnotation(SecurityDomain.class); 

      PermitAll beanUnchecked = (PermitAll) container.resolveAnnotation(PermitAll.class);
      RolesAllowed beanPermissions = (RolesAllowed) container.resolveAnnotation(RolesAllowed.class);
      
      DeclareRoles beanDeclareRolesPerms = (DeclareRoles)container.resolveAnnotation(DeclareRoles.class);

      if (beanUnchecked != null && beanPermissions != null)
      {
         throw new RuntimeException("Cannot annotate a bean with both @Unchecked and @MethodPermissions");
      }

      String ejbName = container.getEjbName();

      //Add the security role references
      if(beanDeclareRolesPerms != null)
      {
         String[] rolerefs = beanDeclareRolesPerms.value();
         int len = rolerefs != null ? rolerefs.length : 0;
         for(int i=0; i < len; i++)
         {
             try
            {
               pc.addToRole(rolerefs[i], new EJBRoleRefPermission(ejbName, rolerefs[i]));
            }
            catch (PolicyContextException e)
            {
               throw new RuntimeException(e);
            } 
         }
      }
      
      //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++)
      {
         Method m = methods[i];
         if (!Modifier.isPublic(m.getModifiers()))
         {
            continue;
         }

         EJBMethodPermission permission = new EJBMethodPermission(ejbName, null, m);
         log.trace("Creating permission: " + permission);

         PermitAll unchecked = (PermitAll) container.resolveAnnotation(m, PermitAll.class);
         RolesAllowed permissions = (RolesAllowed) container.resolveAnnotation(m, RolesAllowed.class);
         DenyAll exclude = (DenyAll) container.resolveAnnotation(m, DenyAll.class);

         int annotationCount = getAnnotationCount(unchecked, permissions, exclude);

         if (annotationCount == 0 && beanPermissions == null && beanUnchecked == null)
         {
            //continue;
            //EJBTHREE-755:Add to unchecked if there are no annotations
            try
            {
               pc.addToUncheckedPolicy(permission);
            }
            catch (PolicyContextException e)
            {
               throw new RuntimeException(e); 
            } 
         }
         else if (annotationCount > 1)
         {
            throw new RuntimeException("You can only use one of @PermitAll, @DenyAll or @RolesAllowed per method");
         }

         try
         {
            //Method level annotations override the bean level annotations
            if (unchecked != null)
            {
               pc.addToUncheckedPolicy(permission);
               log.trace("Adding permission to unchecked policy");
               continue;
            }
            if (permissions != null)
            {
               addToRole(pc, permission, permissions);
               continue;
            }
            if (exclude != null)
            {
               pc.addToExcludedPolicy(permission);
               log.trace("Adding permission to excluded policy");
               continue;
            }

            if (beanUnchecked != null)
            {
               pc.addToUncheckedPolicy(permission);
               log.trace("Adding permission to unchecked policy");
               continue;
            }
            if (beanPermissions != null)
            {
               addToRole(pc, permission, beanPermissions);
               continue;
            }

            //The default is unchecked
            pc.addToUncheckedPolicy(permission);
            log.trace("Adding permission to unchecked policy");
         }
         catch (PolicyContextException e)
         {
            throw new RuntimeException(e);  
         }
      }
   
private static voidaddToRole(javax.security.jacc.PolicyConfiguration pc, javax.security.jacc.EJBMethodPermission p, javax.annotation.security.RolesAllowed mp)

      String[] roles = mp.value();
      for (int i = 0; i < roles.length; i++)
      {
         pc.addToRole(roles[i], p);
         log.trace("Adding permission to role: " + roles[i]);
      }
   
public static voidcheckPermission(java.security.CodeSource ejbCS, javax.security.jacc.EJBMethodPermission methodPerm, org.jboss.security.RealmMapping realmMapping)

      try
      {
         Policy policy = Policy.getPolicy();
         // Get the caller
         Subject caller = SecurityActions.getContextSubject();
  
         RunAsIdentity rai = SecurityActions.peekRunAsIdentity();

         Principal[] principals = null;
         if(rai != null)
         {
            Set runAsRoles = rai.getRunAsRoles();
            principals = new Principal[runAsRoles.size()];
            runAsRoles.toArray(principals); 
         }
         else
         {
            /*if (caller != null)
            {
               // Get the caller principals
               Set principalsSet = caller.getPrincipals();
               principals = new Principal[principalsSet.size()];
               principalsSet.toArray(principals);
            }*/
            //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);
         } 
         
         ProtectionDomain pd = new ProtectionDomain(ejbCS, null, null, principals);
         if (policy.implies(pd, methodPerm) == false)
         {
            String msg = "Denied: " + methodPerm + ", caller=" + caller;
            //SecurityException e = new SecurityException(msg);
            EJBAccessException e = new EJBAccessException(msg);
            throw e;
         }
      }
      catch (PolicyContextException e)
      {
         throw new RuntimeException(e);
      }
   
public static voidconfigureContainer(java.lang.String jaccContextId, org.jboss.ejb3.EJBContainer container)

      try
      {
         addJaccContextToContainer(jaccContextId, container);
         PolicyConfigurationFactory pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory();
         PolicyConfiguration pc = pcFactory.getPolicyConfiguration(jaccContextId, false);

         addPermissions(container, pc);
      }
      catch (Exception e)
      { 
         throw new RuntimeException(e);
      }
   
private static intgetAnnotationCount(javax.annotation.security.PermitAll u, javax.annotation.security.RolesAllowed mp, javax.annotation.security.DenyAll e)

      int annotations = 0;
      if (u != null) annotations++;
      if (mp != null) annotations++;
      if (e != null) annotations++;

      return annotations;
   
public static javax.security.jacc.PolicyConfigurationinitialiseJacc(java.lang.String contextID)
Creates a new policy configuration on (re)deployment. Context ID used is based on name of app, so we make sure we clean out any existing policy with that id.


                                    
         
   
      log.trace("Initialising JACC Context for deployment: " + contextID);
      PolicyConfigurationFactory pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory();
      boolean removeExistingContext = true;
      PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, removeExistingContext);

      /*Set keys = PolicyContext.getHandlerKeys();
      if (!keys.contains(EnterpriseBeanPolicyContextHandler.EJB_CONTEXT_KEY))
      {
         EnterpriseBeanPolicyContextHandler beanHandler = new EnterpriseBeanPolicyContextHandler();
         PolicyContext.registerHandler(EnterpriseBeanPolicyContextHandler.EJB_CONTEXT_KEY,
               beanHandler, false);
      }
      */
      //Do I need this?
      /*BeanMetaDataPolicyContextHandler metadataHandler = new BeanMetaDataPolicyContextHandler();
      PolicyContext.registerHandler(BeanMetaDataPolicyContextHandler.METADATA_CONTEXT_KEY,
         metadataHandler, false);*/
      /*
      if (!keys.contains(EJBArgsPolicyContextHandler.EJB_ARGS_KEY))
      {
         EJBArgsPolicyContextHandler argsHandler = new EJBArgsPolicyContextHandler();
         PolicyContext.registerHandler(EJBArgsPolicyContextHandler.EJB_ARGS_KEY,
               argsHandler, false);
      }
      */
      return pc;
   
public static voidputJaccInService(javax.security.jacc.PolicyConfiguration pc, org.jboss.deployment.DeploymentInfo di)

      di.context.put("javax.security.jacc.PolicyConfiguration", pc);

      // Link this to the parent PC
      DeploymentInfo current = di;
      while (current.parent != null)
      {
         current = current.parent;
      }

      PolicyConfiguration parentPC = (PolicyConfiguration)
              current.context.get("javax.security.jacc.PolicyConfiguration");

      if (parentPC != null && parentPC != pc)
      {
         parentPC.linkConfiguration(pc);
      }

      pc.commit();
      log.trace("JACC Policy Configuration for deployment has been put in service");
   
public static voidunregisterJacc(java.lang.String contextID)

      PolicyConfigurationFactory pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory();
      PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, true);
      pc.delete();