Change By: Carlo de Wolf (19/Mar/14 5:19 AM)
Description: There are two issues regarding the isCallerInRole() jacc compliance:



1. isCallerInRole should use jacc when jacc is enabled

2. EJBRoleRefPermissions should be created  


 


Here some hints to simplify resolving these issues. Please consider also not calling always Policy.getPolicy() to improve the performance when the security manager is enabled. In ejb 2.x the jaccEnabled flag is set by the JaccAuthorizationInterceptor, this is probably also a good idea for the ejb 3.0 implementation.



When fixing this issue, consider also fixing http://jira.jboss.com/jira/browse/EJBTHREE-704 (Missing privileged action to get Principal), it's an oneliner and in the same java class.



{code:title=
org.jboss.ejb3 .BaseSessionContext :
...
}
   private Policy policy;



   private boolean jaccEnabled;



   public boolean isCallerInRole(String roleName)

   {

  if (jaccEnabled) {

   return isCallerInRoleCheckForJacc(roleName);

  }

 ...





   // This code bases on code from org.jboss.ejb.EnterpriseContext

   private boolean isCallerInRoleCheckForJacc(String roleName)

   {

      //This has to be the EJBRoleRefPermission

      String ejbName = container.getEjbName();

      EJBRoleRefPermission ejbRoleRefPerm = new EJBRoleRefPermission(ejbName,roleName);

      //Get the caller

      Subject caller;

      try

      {

         caller = JPSecurityActions.getContextSubject();

      }

      catch (PolicyContextException e)

      {

         throw new RuntimeException(e);

      }

      Principal[] principals = null;

      if( caller != null )

      {

         // Get the caller principals

         Set principalsSet = caller.getPrincipals();

         principals = new Principal[principalsSet.size()];

         principalsSet.toArray(principals);       
      
      }

      CodeSource ejbCS = container.getBeanClass().getProtectionDomain().getCodeSource();

      ProtectionDomain pd = new ProtectionDomain (ejbCS, null, null, principals);

      // getting the policy is checked by the security manager -> cache it lazy

      if (policy == null) {

       policy = Policy.getPolicy();

      }

      return policy.implies(pd, ejbRoleRefPerm);   
  
   }    

   

   public Principal getCallerPrincipal()

   {

  // @EJBTHREE-704:

  //Principal principal = SecurityAssociation.getCallerPrincipal();

  Principal principal = SecurityActions.getCallerPrincipal();

      if (getRm() != null)

      {

         principal = getRm().getPrincipal(principal);

      }



      // This method never returns null.

      if (principal == null)

         throw new java.lang.IllegalStateException("No valid security context for the caller identity");



      return principal;

   }





{code}



{code:title=
org.jboss.ejb3.security.JaccHelper

}

// when the security manager is  enabled, caching the policy is a good idea to improve the performace

static Policy policy = Policy.getPolicy();

public static void putJaccInService(PolicyConfiguration pc, DeploymentInfo di) throws Exception

   {

...

      // update the policy

      policy = Policy.getPolicy();

   }



...

   private static void addPermissions(EJBContainer container, PolicyConfiguration pc) {

    ...

      // TODO isn't there a meta data api which should do step 1, 2 and 3?

      // key=role name used in the ejb, value = role link (role name in the security system)

      Map<String,String> roleRefs = new HashMap<String,String>();

      // 1. get declared roles fom the DeclareRoles annotation

      DeclareRoles declareRolesAnnotation = (DeclareRoles) container.getBeanClass().getAnnotation(DeclareRoles.class);

      if (declareRolesAnnotation != null) {

      for (String role : declareRolesAnnotation.value()) {

       roleRefs.put(role, role);

      }

      }

      // 2. probably there are security-role's in the deployment descriptor (assembly-descriptor)

      AssemblyDescriptor assemblyDescriptor = container.getAssemblyDescriptor();

      if (assemblyDescriptor != null) {

      List<SecurityRole> securityRoles = assemblyDescriptor.getSecurityRoles();

      if (securityRoles != null) {

      for (SecurityRole securityRole : securityRoles) {

       roleRefs.put(securityRole.getRoleName(),securityRole.getRoleName());

      }

      }

      }

      // 3. probably there are security-role-ref in the deplyment descriptor for this bean, add them

      // !!! security-role-ref currently not supported by an api, should be fixed in http://jira.jboss.com/jira/browse/EJBTHREE-808

      // 4. add the EJBRoleRefPermission to the jacc provider

      try {

      for( Entry<String, String> roleRefEntry: roleRefs.entrySet() ){

         EJBRoleRefPermission p = new EJBRoleRefPermission(ejbName, roleRefEntry.getKey());

         pc.addToRole(roleRefEntry.getValue(), p);

      }

      } catch (PolicyContextException e) {

       throw new RuntimeException(e);

     }

}


{code}
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira