]
RH Bugzilla Integration commented on SECURITY-744:
--------------------------------------------------
Jitka Kozana <jkudrnac(a)redhat.com> changed the Status of [bug
WebJASPIAuthenticator doesn't populate Subject when building
JBossGenericPrincipal
----------------------------------------------------------------------------------
Key: SECURITY-744
URL:
https://issues.jboss.org/browse/SECURITY-744
Project: PicketBox
Issue Type: Feature Request
Reporter: arjan tijms
Assignee: Stefan Guilhen
Labels: authentication, ejb, jaspi, jaspic, security
{{WebJASPIAuthenticator}} creates a new Subject that it passes to the JASPIC Auth Module
(SAM):
{code}
Subject clientSubject = new Subject();
if (sam != null) {
result = sam.isValid(messageInfo, clientSubject, messageLayer, appContext, cbh);
}
{code}
[
Source|https://github.com/wildfly/wildfly/blob/master/web/src/main/java/o...]
Afterwards this Subject instance is put into the {{JBossGenericPrincipal}} when this is
being build:
{code}
protected Principal buildJBossPrincipal(Subject subject, Principal principal,
GroupPrincipalCallback gpc) {
// ...
// build and return the JBossGenericPrincipal.
return new JBossGenericPrincipal(realm, principal.getName(), null, roles, principal,
null, null, null, subject);
}
{code}
[
Source|https://github.com/wildfly/wildfly/blob/master/web/src/main/java/o...]
This seems to assume that the JASPIC Auth Module has populated the Subject (as happens
with JAAS login modules), but this is not what happens. JASPIC Auth Modules unlike JAAS
login modules are universal and have no knowledge of the container specific Subject
layout.
The container should thus populate the Subject based on the callbacks.
{{WebJASPIAuthenticator}} does uses the callbacks to store the caller/user principal and
roles directly into the {{JBossGenericPrincipal}}. Calls like
{{HttpServletRequest#getUserPrincipal}} directly return
{{JBossGenericPrincipal#getUserPrincipal}} and thus work.
However, {{EJBContext#getCallerPrincipal()}} which is implemented by
{{org.jboss.as.security.service.SimpleSecurityManager#getCallerPrincipal}} works with
{{securityContext.getSubjectInfo().getAuthenticatedSubject}} and does _not_ work.
This {{SubjectInfo}} is initialized in
{{org.jboss.as.web.security.SecurityContextAssociationValve}} via the following code:
{code}
sc.getUtil().createSubjectInfo(new SimplePrincipal(
principal.getName()),
principal.getCredentials(),
principal.getSubject() // clientSubject from JASPIC SAM
);
{code}
(principal here is the {{JBossGenericPrincipal}} that's returned by
{{WebJASPIAuthenticator}})
Because the Subject instance used here is still the empty instance, the authenticated
identity will not be available in EJB beans. {{EJBContext#getCallerPrincipal()}} will
always return the anonymous principal and every check for a role will return false.
Adding something like the following code to {{buildJBossPrincipal}} seems to propagate
the authenticated identity correctly to the EJB module:
{code}
Subject authenticatedSubject = new Subject();
// Add the caller principal to the Subject
Group callerPrincipalGroup = new SimpleGroup("CallerPrincipal");
callerPrincipalGroup.addMember(principal);
authenticatedSubject.getPrincipals().add(callerPrincipalGroup);
// Add the roles to the Subject
if (!roles.isEmpty()) {
Group rolesGroup = new SimpleGroup("Roles");
for (String role : roles) {
rolesGroup.addMember(new SimplePrincipal(role));
}
authenticatedSubject.getPrincipals().add(rolesGroup);
}
return new JBossGenericPrincipal(realm, principal.getName(), null, roles, principal,
null, null, null, authenticatedSubject);
{code}
I've tested
[
locally|https://github.com/javaeekickoff/jboss-as-jaspic-patch/commit/31b...]
with this patch and it indeed seems to work.