2 Replies Latest reply on Aug 18, 2008 4:38 PM by crimsontwilightx

    Custom Login Module Issues.

    rob_blake

      Hi folks,

      I've been trying to add a custom login module for Jboss Portal so that we can authenticate our users against a datasource accessible via a web service. I'm having a few issues getting this to work and any pointers would be helpful

      Firstly:

      Portal 2.6
      Jboss AS 4.05 GA

      The approach I have taken is to extend the IdentityLoginModule and override the initialize(), getRoleSets() and validatePasswords() method.

      The relevant code sections are included below:


      public void initialize(Subject subject,CallbackHandler handler,Map sharedState,Map options)
      {
      super.initialize(subject,handler,sharedState,options);

      this.additionalRole = (String)options.get("additionalRole");
      this.hashAlgorithm = (String)options.get("hashAlgorithm");
      this.hashEncoding = (String)options.get("hashEncoding");
      this.hashCharset = (String)options.get("hashCharset");
      this.userModuleJNDIName = (String)options.get("userModuleJNDIName");
      this.roleModuleJNDIName = (String)options.get("roleModuleJNDIName");
      this.userProfileModuleJNDIName = (String)options.get("userProfileModuleJNDIName");
      this.membershipModuleJNDIName = (String)options.get("membershipModuleJNDIName");

      if(options.containsKey("ignorePasswordCase"))
      {
      this.ignorePasswordCase = ((String)options.get("ignorePasswordCase")).equalsIgnoreCase("true");
      }

      this.endpoint = (String)options.get("serviceEndPoint");
      this.wsdlLocation = (String)options.get("serviceWSDL");
      this.namespace = (String)options.get("serviceNamespace");
      }


      The initialize method calls the super.initialize(), and then simply stores values of our jndi services for Portal User/Role/Membership creation and also the endpoints of of WS.


      protected Group[] getRoleSets() throws LoginException
      {
      Group rolesGroup = new SimpleGroup("Roles");
      rolesGroup.addMember(createIdentity("Authenticated"));
      rolesGroup.addMember(createIdentity("Users"));

      return new Group[]{rolesGroup};
      }


      public Principal createIdentity(String username)
      {
      return new UserPrincipal(username);
      }


      The getRoleSets() method is hardcoded to return the roles of Users and Authenticated which is fine for our needs.

      Finally I have the overridden validatePassword() method. At the minute the password verification simply returns true so that I can get this thing working (it will of course verify the given password against that returned by the WS call). The user is then added to the portal user database by making use of UserModule, RoleModule and MembershipModule respectively if they do not already have a portal db presence.


      protected boolean validatePassword(String password,String expectedPassword)
      {

      if(!this.checkPassword(password, expectedPassword))
      return false;

      // If the user is present in the portal DB, we simply return.
      if(this.getUserStatus(password) == UserStatus.OK)
      {
      return true;
      }

      try
      {
      this.addUserToPortalDB(getIdentity().getName(),password);
      }
      catch(IdentityException e)
      {
      logger.debug(cn + ".validatePassword() - Cannot add User to Portal Database: " + e.getMessage());
      e.printStackTrace();
      return false;
      }

      return true;
      }


      private boolean checkPassword(String password,String expectedPassword) {
      return true;
      }

      private User addUserToPortalDB(final String username,final String userPass) throws IdentityException
      {
      try
      {
      TransactionManager tm = this.getTransactionManager();
      return (User)Transactions.required(tm,new Transactions.Runnable()
      {
      public Object run() throws Exception
      {
      User user = getUserModule().createUser(username,userPass);
      Set roleSet = new HashSet();

      if(user.getUserName().equalsIgnoreCase("admin"))
      {
      roleSet.add(getRoleModule().findRoleByName("Admin"));
      }


      roleSet.add(getRoleModule().findRoleByName("User"));

      getMembershipModule().assignRoles(user,roleSet);
      getUserProfileModule().setProperty(user,User.INFO_USER_ENABLED,new Boolean(true));

      return user;
      }
      });
      }
      catch(NamingException e)
      {
      logger.info(cn + ".addUserToPortalDB() - NamingException Looking Up UserModule");
      throw new IdentityException(e);
      }
      catch(Exception e)
      {
      logger.info(cn + ".addUserToPortalDB() - Exception during Transaction");
      throw new IdentityException(e);
      }
      }


      I have altered my jboss-portal.sar/conf/login-config.xml to include the following


      <login-module code="com.restfurl.portal.jaas.authentication.TraderLoginModule" flag="requisite">
      <module-option name="userModuleJNDIName">java:/portal/UserModule</module-option>
      <module-option name="roleModuleJNDIName">java:/portal/RoleModule</module-option>
      <module-option name="userProfileModuleJNDIName">java:/portal/UserProfileModule</module-option>
      <module-option name="membershipModuleJNDIName">java:/portal/MembershipModule</module-option>
      <module-option name="additionalRole">Authenticated</module-option>
      <module-option name="serviceEndPoint">http://localhost:8080/analystServices/analyst</module-option>
      <module-option name="serviceWSDL">http://localhost:8080/analystServices/analyst?wsdl</module-option>
      <module-option name="serviceNamespace">com.restfurl.portal.services.namespaces</module-option>
      <module-option name="ignorePasswordCase">true</module-option>
      <module-option name="password-stacking">useFirstPass</module-option>
      </login-module>
      <login-module code="org.jboss.portal.identity.auth.IdentityLoginModule" flag="required">
      <module-option name="unauthenticatedIdentity">guest</module-option>
      <module-option name="userModuleJNDIName">java:/portal/UserModule</module-option>
      <module-option name="roleModuleJNDIName">java:/portal/RoleModule</module-option>
      <module-option name="userProfileModuleJNDIName">java:/portal/UserProfileModule</module-option>
      <module-option name="membershipModuleJNDIName">java:/portal/MembershipModule</module-option>
      <module-option name="additionalRole">Authenticated</module-option>
      <module-option name="password-stacking">useFirstPass</module-option>
      </login-module>


      The code for my LoginModule is packaged as a .jar file and I have this included in jboss-portal.sar/lib. Is this the correct place for the .jar?

      When attempting to use my LoginModule, the only output I receive on the login.jsp is "null". I do not seem to get any errors on system output or any exceptions.

      If anyone can offer any suggestions, it would be mighty appreciated.

      cheers

      Rob

        • 1. Re: Custom Login Module Issues.
          den74

          i'm using 2.4.1 portal so i'm not sure it will be useful for you. What i did is:
          - altered conf/login-config.xml (not the one under jboss-portal.sar) configuring my application-policy
          - altered portal-server.war\WEB-INF\jboss-web to use my new application-policy
          - put my jar library under portal lib folder (the one under default)

          i hope my experience can help you in some way

          • 2. Re: Custom Login Module Issues.
            crimsontwilightx

            hi,

            the problem is : login module class must be in system class path.

            happy news is that you can use ProxyLoginModule instead of directly declaring your class. look at the config file :

            <login-module code="org.jboss.security.auth.spi.ProxyLoginModule" flag="required">
             <module-option name="moduleName">org.jboss.portal.core.identity.MyLoginModule</module-option>
             <module-option name="unauthenticatedIdentity">guest</module-option>
             <module-option name="userModuleJNDIName">java:/portal/UserModule</module-option>
             <module-option name="roleModuleJNDIName">java:/portal/RoleModule</module-option>
             <module-option name="userProfileModuleJNDIName">java:/portal/UserProfileModule</module-option>
             <module-option name="membershipModuleJNDIName">java:/portal/MembershipModule</module-option>
             <module-option name="additionalRole">Authenticated</module-option>
             </login-module>


            for further : http://docs.jboss.org/jbossas/admindevel326/html/ch8.chapter.html

            best regards