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