Uploaded image for project: 'PicketBox '
  1. PicketBox
  2. SECURITY-744

WebJASPIAuthenticator doesn't populate Subject when building JBossGenericPrincipal

XMLWordPrintable

      WebJASPIAuthenticator creates a new Subject that it passes to the JASPIC Auth Module (SAM):

      Subject clientSubject = new Subject();
      if (sam != null) {
          result = sam.isValid(messageInfo, clientSubject, messageLayer, appContext, cbh);
      }
      

      Source

      Afterwards this Subject instance is put into the JBossGenericPrincipal when this is being build:

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

      Source

      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:

      sc.getUtil().createSubjectInfo(new SimplePrincipal(
          principal.getName()), 
          principal.getCredentials(),
          principal.getSubject() // clientSubject from JASPIC SAM
      );
      

      (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:

      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);
      
      

      I've tested locally with this patch and it indeed seems to work.

              Unassigned Unassigned
              arjan.tijms@gmail.com Arjan Tijms (Inactive)
              Votes:
              5 Vote for this issue
              Watchers:
              9 Start watching this issue

                Created:
                Updated: