I couldn't get he example to run because it is missing the CustomRealm
class. One issue I see it the use of the OpenEJB
LocalInitialContextFactory. When integrated into Tomcat JNDI ejb
references and @EJB injection work automatically, so there is no need
to use the LocalInitialContextFactory. This is unlikely the cause of
the security problems you are seeing unless you try to login using the
context. I'd just remove all the JNDI code and rely on injection...
it will just work.
On Aug 22, 2008, at 4:13 PM, Dain Sundstrom wrote:
Sorry, I haven't responded earlier... been kinda off the grid lately.
This is really weird. The code is designed to pickup the real
associated the web app and propagate it to the EJB container (see
TomcatSecurityService.enterWebApp(Realm realm, Principal principal,
String runAs). The defaultRealm in the code is only used for EJB
calls from a remote VM.
As you mentioned TomcatSecurityService should override
isCallerInRole() which is part of the problem you are seeing, but
I'm not sure it is all of it.
After further reading, the TomcatSecurityService shouldn't override
isCallerInRole. This code is very tricky, but is required by the JACC
JEE spec to be implemented this way. Here is the code for the
isCallerInRole method:
public boolean isCallerInRole(String role) {
if (role == null) throw new IllegalArgumentException("Role
must not be null");
ThreadContext threadContext = ThreadContext.getThreadContext();
SecurityContext securityContext =
threadContext.get(SecurityContext.class);
try {
CoreDeploymentInfo deployment =
threadContext.getDeploymentInfo();
securityContext.acc.checkPermission(new
EJBRoleRefPermission(deployment.getEjbName(), role));
} catch (AccessControlException e) {
return false;
}
return true;
}
This method redirects the isCallerInRole to a VM security check for
the permission EJBRoleRefPermission. The trick is we have installed a
JACC compliant java.security.Policy. When the security
checkPermission method is executed, the call is redirected to
BasicPolicyConfiguration.implies(ProtectionDomain, Permission) which
in turn call back into the TomcatSecurityService getLogicalRoles
method. This trip through the VM security lay is required by the JACC
spec and gives the user a spec-compliant way to completely replace the
authroization system.
The net effect is we call
user.getRealm().hasRole(user.getTomcatPrincipal(), logicalRole) to
determine if a user has a role. The realm is the realm we received in
the OpenEJBValve when the application was entered.
I'm going to play with the security ejb-examples we have for Tomcat to
see if I can reproduce the error you are seeing.
-dain