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]