EJB getCallerPrincipal inconsistencies
starksm64 Jan 13, 2006 2:25 PMRelated to http://jira.jboss.com/jira/browse/JBAS-2551
ejb3:
public Principal getCallerPrincipal() { Principal principal = SecurityAssociation.getCallerPrincipal(); if (getRm() != null) { principal = getRm().getPrincipal(principal); } // This method never returns null. if (principal == null) throw new java.lang.IllegalStateException(); return principal; }
in ejb2.1, the much more convoluted:
Principal getCallerPrincipalInternal() { if (beanPrincipal == null) { RealmMapping rm = con.getRealmMapping(); if (principal != null) { if (rm != null) beanPrincipal = rm.getPrincipal(principal); else beanPrincipal = principal; } else if (rm != null) { // Check for the caller's run-as identity, not this bean's run-as beanPrincipal = SecurityActions.peekRunAsIdentity(1); if (beanPrincipal == null) { // Let the RealmMapping map the null principal beanPrincipal = rm.getPrincipal(principal); } } else { // Check for a unauthenticated principal value ApplicationMetaData appMetaData = con.getBeanMetaData().getApplicationMetaData(); String name = appMetaData.getUnauthenticatedPrincipal(); if (name != null) beanPrincipal = new SimplePrincipal(name); } } if( beanPrincipal == null ) { throw new IllegalStateException("No valid security context for the caller identity"); } return beanPrincipal; }
Both are not handling the identity correctly in all circumstances. In the ejb3 case:
- the call to the RealmMapping.getPrincipal(Principal) should really only be called when there is not a run-as identity. This probably never causes a problem because the run-as identity is not likely the identity mapping depends on the getPrincipal argument corresponding to the authenticated principal in the cache, and this should not be the run-as principal name.
- the ear metadata is not being consulted for an unauthenticated principal for the case of both the SecurityAssociation.getCallerPrincipal() and RealmMapping.getPrincipal() returning null. This is the appMetaData.getUnauthenticatedPrincipal() related block in the ejb2.1 case.
In the ejb2.1 case:
- The run-as identity should be caller identity if it exists. The current code should be simplified to use the SecurityAssociation.getCallerPrincipal() as this is its logic. Currently if there is an authenticated that is what is being used.
There are a number of getCallerPrincipal testcases, but not one comprehensive testcase going over all of the various permutations apparently. I'll work on that.