1 Reply Latest reply on Oct 7, 2013 1:30 PM by Anil Saldanha

    Picketlink replacement for org.jboss.seam.security.Identity

    Chris Martin Newbie

      I am trying to migrate a Seam 2.3 application to CDI. I was using Jboss security  in order to be able to override the Seam identity class so I  can use the JBoss Negotiation package for Kerberos  authentication.  The class uses the JBoss security packages to retrieve the authenticated user  information for authorization. I have found that

      picketlink has the following classes:

       

      org.picketlink.idm.api.Identity

      org.picketlink.idm.api.Credential

      org.picketlink.idm.api.Role

       

      but  cannot find a replacement for org.jboss.security.SecurityContextAssociation for access to the javax.security.auth.Subject in order to get access to the Principals.  This can be seen in the initialize method below.  I have  searched the documentation but cannot find anything. Can someone provide some direction as to how to rewrite this. Does picketlink support this ?

       

       

       

      package com.session;

      import com.common.security.UserPrincipal;

      import org.jboss.seam.ScopeType;

      import org.jboss.seam.annotations.Install;

      import org.jboss.seam.annotations.Logger;

      import org.jboss.seam.annotations.Name;

      import org.jboss.seam.annotations.Scope;

      import org.jboss.seam.annotations.Startup;

      import org.jboss.seam.annotations.intercept.BypassInterceptors;

      import org.jboss.seam.log.Log;

      import org.jboss.seam.security.Credentials;

      import org.jboss.seam.security.Identity;

      import org.jboss.seam.security.Role;

      import org.jboss.security.SecurityContextAssociation;

      import javax.security.auth.Subject;

      import java.security.Principal;

      import java.security.acl.Group;

      import java.util.Set;

       

       

      /**

      * Overriding the Seam identity class so we can use the JBoss Negotiation package for Kerberos

      * authentication.  The class uses the JBoss security packages to retrieve the authenticated user

      * information for authorization.   The identity assumes that the UserPrinciple class has been

      * associated with the JAAS Subject from the Login Module.

      */

      @SuppressWarnings("serial")

      @Name("org.jboss.seam.security.identity")

      @Scope(ScopeType.SESSION)

      @Install(precedence = Install.APPLICATION)

      @BypassInterceptors

      @Startup

      public class UserIdentity extends Identity {

      // ------------------------------ FIELDS ------------------------------

       

       

        @Logger

        private Log log;

       

       

        private Subject subject;

        private UserPrincipal principal;

        private boolean initialized;

       

       

        // -------------------------- METHODS --------------------------

       

       

        @Override

        public Principal getPrincipal() {

          if (principal == null) {

            initialize();

          }

       

       

          return principal;

        }

       

       

        /**

         * Initialize the subject and principle for the object.  There is an assumption that the JBoss

         * JAAS authentication has occurred and is stored in the SecurityAssociation object.

         * <p/>

         * Also the method assumes a UserPrincipal has been created.

         */

        private synchronized void initialize() {

          if (initialized) {

            return;

          }

       

          subject = SecurityContextAssociation.getSubject();

          if (subject == null) {

            return;

          }

       

       

          Set<UserPrincipal> principalSet = subject.getPrincipals(UserPrincipal.class);

          if (principalSet == null || principalSet.isEmpty()) {

            log.error("ERROR WITH USER AUTHORIZATION.  Unable to find the " + UserPrincipal.class + " in the JAAS subject.");

            return;

          }

       

       

          principal = (UserPrincipal) principalSet.toArray()[0];

       

       

          //Set the username and password so the credentials object is consider "valid" to

          //the super class.  We will use a dummy password since the user has already been

          //validate in the JBoss JAAS setup.

          Credentials credentials = getCredentials();

          credentials.setUsername(principal.getName());

          credentials.setPassword("dummy");

       

       

          //Tell super class that we already have a valid principal

          acceptExternallyAuthenticatedPrincipal(principal);

       

       

          log.debug(credentials.getUsername() + " credentials and principal successfully configured");

       

       

          initialized = true;

          log.debug("Initialization of UserIdentity complete");

        }

       

       

        /**

         * Overriding method because we need to use the Subject from JBoss JAAS instead of the one from

         * the super class.

         *

         * @return the Subject from the JBoss JAAS authentication

         */

        @Override

        public Subject getSubject() {

          if (subject == null) {

            initialize();

          }

       

       

          return (subject == null) ? new Subject() : subject;

        }

       

       

        /**

         * Checks if the authenticated user is a member of the specified role. Overrode method because the

         * seam identity tries to login again and since we are using JBoss JAAS the login will not work.

         *

         * @param role String The name of the role to check

         * @return boolean True if the user is a member of the specified role

         */

        @Override

        public boolean hasRole(String role) {

          if (!securityEnabled) {

            return true;

          }

       

       

          Set<Group> groups = getSubject().getPrincipals(Group.class);

          for (Group group : groups) {

            if (ROLES_GROUP.equals(group.getName())) {

              return group.isMember(new Role(role));

            }

          }

       

       

          return false;

        }