1 Reply Latest reply on Jan 17, 2013 6:28 AM by sanssan

    JBoss AS 7 - Custom Login Module - Migration from JBoss 3.x

    sanssan

      Friends,

       

      We are migrating from JBoss 3.x to JBoss 7.1.1.Final (Finally, ).

       

      We do have following configuration to call our login module class, which validate agains LDAP server and return boolean.

       

      <application-policy name="ldap_web_client_security">
                      <authentication>
                              <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"/>
                              <login-module code="com.xyz.abc.LdapLogin.GenericLDAPLoginModule" flag="required"/>
                      </authentication>
              </application-policy>
      

      I tried to move this configuration to standalone.xml on JBoss AS 7.

       

                     <security-domain name="ldap_web_client_security" cache-type="default">
                          <authentication>
                              <login-module code="org.jboss.security.ClientLoginModule" flag="required"/>
                              <login-module code="com.xyz.abc.LdapLogin.GenericLDAPLoginModule" module="com.xyz.ldap" flag="required"/>
                          </authentication>
                      </security-domain>
      

       

      [or]

                     <security-domain name="ldap_web_client_security" cache-type="default">
                          <authentication>
                              <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"/>
                              <login-module code="com.xyz.abc.LdapLogin.GenericLDAPLoginModule" module="com.xyz.ldap" flag="required"/>
                          </authentication>
                      </security-domain>
      

      Where as my GenericLDAPLoginModule class as given below for LDAP Active Directory search...

       

      package com.xyz.abc.LdapLogin;
      
      import java.util.Hashtable;
      
      import javax.naming.NamingEnumeration;
      import javax.naming.NamingException;
      import javax.naming.directory.Attributes;
      import javax.naming.directory.DirContext;
      import javax.naming.directory.SearchControls;
      import javax.naming.directory.SearchResult;
      import javax.naming.ldap.InitialLdapContext;
      
      import org.apache.log4j.Logger;
      
      /**
       * @author SanthoshK
       * 
       */
      public class GenericLDAPLoginModule implements LoginModule {
      
          private static Logger LOGGER = Logger.getLogger(GenericLDAPLoginModule.class);
      
          private String password = null;
          private String userName = null;
      
          public GenericLDAPLoginModule(String userName, String password){
              this.userName = userName;
              this.password = password;
          }
      
          public String toString() {
              return this.userName;
          }
          public boolean authenticate() {  
      
              try {  
                  LOGGER.info("authenticate - START");  
      
                  LOGGER.info("Attempting to validate user : ["+this.userName+"]");  
      
                  GenericLDAPLoginUtil genericLDAPLoginUtil = new GenericLDAPLoginUtil();  
      
                  Hashtable<String, String> envHTable = getEnvironmentTable();  
      
                  DirContext ctx = new InitialLdapContext(envHTable, null);  
                  SearchControls searchCtls = new SearchControls();  
                  String returnedAtts[] = { "cn", "givenName" };  
                  searchCtls.setReturningAttributes(returnedAtts);  
                  searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);  
      
                  String searchFilter = "(&(sAMAccountName=" + this.userName + ")(objectCategory=user))";  
                  String searchBase = "DC=group,DC=net";  
      
                  int totalResults = 0;  
                  NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);  
                  String ouName = null;  
                  while (answer.hasMoreElements()) {  
                      SearchResult searchResult = answer.next();  
                      totalResults++;  
                      ouName = searchResult.getName();  
                      Attributes attrs = searchResult.getAttributes();  
                      if (attrs != null) {  
                          try {  
                              LOGGER.info(" surname: " + attrs.get("cn").get());  
                              LOGGER.info(" firstname: " + attrs.get("givenName").get());  
                          } catch (NullPointerException e) {  
                              LOGGER.info("Errors listing attributes: " + e);  
                          }  
                      }  
                  }  
                  LOGGER.info("Total results: " + totalResults);  
                  ctx.close();  
                  if (totalResults > 0) {  
                      String adminName = ouName + ",dc=group,dc=net";  
                      envHTable = getEnvironmentTable(adminName,this.password);  
      
                      DirContext ctx1 = new InitialLdapContext(envHTable, null);  
                      ctx1.close();  
                      return true;  
                  } else {  
                      return false;  
                  }  
              } catch (NamingException exception) {  
                  LOGGER.error("Problem searching directory: " + exception);  
                  return false;  
              } catch (Exception exception) {  
                  LOGGER.error("Unhandled Exception: " + exception);  
                  return false;  
              } finally {  
                  LOGGER.info("authenticate - END");  
              }  
          }  
      
      public Hashtable<String, String> getEnvironmentTable(String aName, String aPassword, String newUrl){  
              Hashtable<String, String> envHTable = new Hashtable<String, String>();  
              envHTable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");  
              envHTable.put(Context.SECURITY_AUTHENTICATION, "simple");  
              envHTable.put(Context.SECURITY_PRINCIPAL, aName);  
              envHTable.put(Context.SECURITY_CREDENTIALS, aPassword);  
              envHTable.put(Context.PROVIDER_URL, newUrl);  
              LOGGER.info("envHashTable : " + envHTable);  
              return envHTable;  
          }  
      
          public Hashtable<String, String> getEnvironmentTable(){  
              return getEnvironmentTable("LDapAdminName", "password", "ldap://MyLDAPServerName:389");  
          }  
      
          public Hashtable<String, String> getEnvironmentTable(String aName, String aPassword){  
              return getEnvironmentTable(aName, aPassword, "ldap://MyLDAPServerName:389");  
          }
      }
      

       

      But, it fails with an Exception :

      15:29:26,749 ERROR [org.jboss.security.authentication.JBossCachedAuthenticationManager] (http--127.0.0.1-8180-1) Login failure: javax.security.auth.login.LoginException: unable to instantiate LoginModule, com.xyz.abc.LdapLogin.GenericLD
      APLoginModule, because it does not provide a no-argument constructor
              at javax.security.auth.login.LoginContext.invoke(LoginContext.java:816) [rt.jar:1.7.0]
              at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203) [rt.jar:1.7.0]
              at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698) [rt.jar:1.7.0]
              at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696) [rt.jar:1.7.0]
              at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.7.0]
              at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:695) [rt.jar:1.7.0]
              at javax.security.auth.login.LoginContext.login(LoginContext.java:594) [rt.jar:1.7.0]
              at org.jboss.security.authentication.JBossCachedAuthenticationManager.defaultLogin(JBossCachedAuthenticationManager.java:449) [picketbox-infinispan-4.0.7.Final.jar:4.0.7.Final]
              at org.jboss.security.authentication.JBossCachedAuthenticationManager.proceedWithJaasLogin(JBossCachedAuthenticationManager.java:383) [picketbox-infinispan-4.0.7.Final.jar:4.0.7.Final]
              at org.jboss.security.authentication.JBossCachedAuthenticationManager.authenticate(JBossCachedAuthenticationManager.java:361) [picketbox-infinispan-4.0.7.Final.jar:4.0.7.Final]
              at org.jboss.security.authentication.JBossCachedAuthenticationManager.isValid(JBossCachedAuthenticationManager.java:160) [picketbox-infinispan-4.0.7.Final.jar:4.0.7.Final]
              at org.jboss.as.web.security.JBossWebRealm.authenticate(JBossWebRealm.java:214) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
              at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:280) [jbossweb-7.0.13.Final.jar:]
              at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:381) [jbossweb-7.0.13.Final.jar:]
              at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
              at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
              at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
              at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
              at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
              at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
              at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
              at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
              at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0]
      
      
      
        • 1. Re: JBoss AS 7 - Custom Login Module - Migration from JBoss 3.x
          sanssan

          Hi,

           

          Thanks all. Found the problem. While migrating, I have pickedup wrong Custom Login Module. Fixed it by....

           

          package com.xyz.ldaplogin.module;
          
          import java.security.acl.Group;
          import java.util.Hashtable;
          
          import javax.naming.NamingEnumeration;
          import javax.naming.NamingException;
          import javax.naming.directory.Attributes;
          import javax.naming.directory.DirContext;
          import javax.naming.directory.SearchControls;
          import javax.naming.directory.SearchResult;
          import javax.naming.ldap.InitialLdapContext;
          import javax.security.auth.login.LoginException;
          
          import org.apache.log4j.Logger;
          import org.jboss.security.SimpleGroup;
          import org.jboss.security.SimplePrincipal;
          import org.jboss.security.auth.spi.LdapExtLoginModule;
          
          import com.xyz.ldaplogin.util.GenericLDAPLoginUtil;
          
          /**
           * @author SanthoshK
           * 
           */
          public class GenericLVLDAPLoginModule extends LdapExtLoginModule {
          
              private static Logger LOGGER = Logger
                      .getLogger(GenericLVLDAPLoginModule.class);
          
              private String xyzUserName;
              private String xyzUserName;
          
              private void assignUserCredentials() throws LoginException {
                  LOGGER.info("assignUserCredentials - START");
                  String[] loginCredentials = null;
                  try {
                      loginCredentials = getUsernameAndPassword();
                      this.xyzUserName = loginCredentials[0];
                      this.xyzUserName = loginCredentials[1];
                  } catch (Exception exception) {
                      LOGGER.error("assignUserCredentials Exception : " + exception);
                      throw new LoginException("Invalid Login Credentials : " + loginCredentials);
                  } finally {
                      LOGGER.info("assignUserCredentials - END");
                  }
              }
          
              @Override
              protected String bindDNAuthentication(InitialLdapContext ctx, String user, Object credential, String baseDN, String filter) throws NamingException {
                  return super.bindDNAuthentication(ctx, user, credential, baseDN, filter);
              }
          
              @Override
              protected void rolesSearch(InitialLdapContext ctx, SearchControls constraints, String user, String userDN, int recursionMax, int nesting) throws NamingException {
                  super.rolesSearch(ctx, constraints, user, userDN, recursionMax, nesting);
              }
          
              @Override
              protected boolean validatePassword(String inputPassword, String expectedPassword) {
                  return validation();
              }
          
              @Override
              protected String getUsersPassword() throws LoginException {
                  return "";
              }
          
              private transient SimpleGroup userRoles = new SimpleGroup("Roles");
          
              @Override
              protected Group[] getRoleSets() throws LoginException {
                  // Add each role to the "Roles" principal (Ref web.xml)
                  userRoles.addMember(new SimplePrincipal("Authenticated_users"));
                  Group[] roleSets = { userRoles };
                  return roleSets;
              }
          
              private boolean validation() {
          
                  try {
                      LOGGER.info("authenticate - START");
          
                      this.assignUserCredentials();
                      LOGGER.info("Attempting to validate user : [" + this.xyzUserName + "]");
          
                      GenericLDAPLoginUtil genericLDAPLoginUtil = new GenericLDAPLoginUtil();
          
                      Hashtable<String, String> envHTable = genericLDAPLoginUtil.getEnvironmentTable();
          
                      DirContext ctx = new InitialLdapContext(envHTable, null);
                      SearchControls searchCtls = new SearchControls();
                      String returnedAtts[] = { "cn", "givenName" };
                      searchCtls.setReturningAttributes(returnedAtts);
                      searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
          
                      String searchFilter = "(&(sAMAccountName=" + this.xyzUserName
                              + ")(objectCategory=user))";
                      String searchBase = "DC=group,DC=net";
          
                      int totalResults = 0;
                      NamingEnumeration<SearchResult> answer = ctx.search(searchBase,
                              searchFilter, searchCtls);
                      String ouName = null;
                      while (answer.hasMoreElements()) {
                          SearchResult searchResult = answer.next();
                          totalResults++;
                          ouName = searchResult.getName();
                          Attributes attrs = searchResult.getAttributes();
                          if (attrs != null) {
                              try {
                                  LOGGER.info(" surname: " + attrs.get("cn").get());
                                  LOGGER.info(" firstname: "
                                          + attrs.get("givenName").get());
                              } catch (NullPointerException e) {
                                  LOGGER.info("Errors listing attributes: " + e);
                              }
                          }
                      }
                      LOGGER.info("Total results: " + totalResults);
                      ctx.close();
                      if (totalResults > 0) {
                          String adminName = ouName + ",dc=group,dc=net";
                          envHTable = genericLDAPLoginUtil.getEnvironmentTable(adminName,
                                  this.xyzUserName);
          
                          DirContext ctx1 = new InitialLdapContext(envHTable, null);
                          ctx1.close();
                          LOGGER.info("AUTHENTICATION ["+this.xyzUserName+"] : PASS");
                          return true;
                      } else {
                          LOGGER.info("AUTHENTICATION ["+this.xyzUserName+"] : FAILED");
                          return false;
                      }
                  } catch (NamingException exception) {
                      LOGGER.error("Problem searching directory: ", exception);
                      return false;
                  } catch (Exception exception) {
                      LOGGER.error("Unhandled Exception: ", exception);
                      return false;
                  } finally {
                      LOGGER.info("authenticate - END");
                  }
              }
          }