Login java con Active Directory
En esta entrada vamos a revisar unas clases que nos permitiran validar los datos de conexión contra un active directory. La aplicación funciona siempre y cuando se encuentre en la red a las cual pertenece dicho dominio.
La clase que vamos a emplear para que valide los datos será la siguiente:
La clase que vamos a emplear para que valide los datos será la siguiente:
public class ActiveDirectoryAuthentication {
private static final String CONTEXT_FACTORY_CLASS = "com.sun.jndi.ldap.LdapCtxFactory";
private String ldapServerUrls[];
private int lastLdapUrlIndex;
private final String domainName;
public ActiveDirectoryAuthentication(String domainName) {
this.domainName = domainName.toUpperCase();
try {
ldapServerUrls = nsLookup(domainName);
} catch (Exception e) {
}
lastLdapUrlIndex = 0;
}
public boolean authenticate(String username, String password) throws LoginException {
if (ldapServerUrls == null || ldapServerUrls.length == 0) {
throw new AccountException("Unable to find ldap servers");
}
if (username == null || password == null || username.trim().length() == 0 || password.trim().length() == 0) {
throw new FailedLoginException("Username or password is empty");
}
int retryCount = 0;
int currentLdapUrlIndex = lastLdapUrlIndex;
do {
retryCount++;
try {
Hashtable<Object, Object> env = new Hashtable<Object, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY_CLASS);
env.put(Context.PROVIDER_URL, ldapServerUrls[currentLdapUrlIndex]);
env.put(Context.SECURITY_PRINCIPAL, username + "@" + domainName);
env.put(Context.SECURITY_CREDENTIALS, password);
DirContext ctx = new InitialDirContext(env);
ctx.close();
lastLdapUrlIndex = currentLdapUrlIndex;
return true;
} catch (CommunicationException exp) {
// TODO you can replace with log4j or slf4j API
exp.printStackTrace();
// if the exception of type communication we can assume the AD
// is not reachable hence retry can be attempted with next
// available AD
if (retryCount < ldapServerUrls.length) {
currentLdapUrlIndex++;
if (currentLdapUrlIndex == ldapServerUrls.length) {
currentLdapUrlIndex = 0;
}
continue;
}
return false;
} catch (Throwable throwable) {
throwable.printStackTrace();
return false;
}
} while (true);
}
private static String[] nsLookup(String argDomain) throws Exception {
try {
Hashtable<Object, Object> env = new Hashtable<Object, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url", "dns:");
DirContext ctx = new InitialDirContext(env);
Attributes attributes = ctx
.getAttributes(String.format("_ldap._tcp.%s", argDomain), new String[]{"srv"});
// try thrice to get the KDC servers before throwing error
for (int i = 0; i < 3; i++) {
Attribute a = attributes.get("srv");
if (a != null) {
List<String> domainServers = new ArrayList<>();
NamingEnumeration<?> enumeration = a.getAll();
while (enumeration.hasMoreElements()) {
String srvAttr = (String) enumeration.next();
// the value are in space separated 0) priority 1)
// weight 2) port 3) server
String values[] = srvAttr.split(" ");
domainServers.add(String.format("ldap://%s:%s", values[3], values[2]));
}
String domainServersArray[] = new String[domainServers.size()];
domainServers.toArray(domainServersArray);
return domainServersArray;
}
}
throw new Exception("Unable to find srv attribute for the domain " + argDomain);
} catch (NamingException exp) {
throw new Exception("Error while performing nslookup. Root Cause: " + exp.getMessage(), exp);
}
}
}
Comentarios