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}
|