JBoss AS 7 - Custom Login Module - Migration from JBoss 3.x
sanssan Jan 10, 2013 7:12 AMFriends,
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]