@Override public User authenticate(final AuthCredentials authCreds) throws AuthException { LdapConnection ldapConnection = null; final String user = authCreds.getUsername(); final char[] password = authCreds.getPassword(); authCreds.clear(); EntryCursor result = null; try { ldapConnection = LDAPAuthorizator.getConnection(settings); final String bindDn = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_BIND_DN, null); if (bindDn != null) { ldapConnection.bind( bindDn, settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_PASSWORD, null)); } else { ldapConnection.anonymousBind(); } result = ldapConnection.search( settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERBASE, ""), settings .get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERSEARCH, "(sAMAccountName={0})") .replace("{0}", user), SearchScope.SUBTREE); if (!result.next()) { throw new AuthException("No user " + user + " found"); } final Entry entry = result.get(); final String dn = entry.getDn().toString(); if (result.next()) { throw new AuthException("More than one user found"); } log.trace("Disconnect {}", bindDn == null ? "anonymous" : bindDn); SecurityUtil.unbindAndCloseSilently(ldapConnection); ldapConnection = LDAPAuthorizator.getConnection(settings); log.trace("Try to authenticate dn {}", dn); ldapConnection.bind(dn, new String(password)); final String usernameAttribute = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERNAME_ATTRIBUTE, null); String username = dn; if (usernameAttribute != null && entry.get(usernameAttribute) != null) { username = entry.get(usernameAttribute).getString(); } log.debug("Authenticated username {}", username); return new LdapUser(username, entry); } catch (final Exception e) { log.error(e.toString(), e); throw new AuthException(e); } finally { if (result != null) { result.close(); } SecurityUtil.unbindAndCloseSilently(ldapConnection); } }
@Override public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) throws AuthException { final String authenticatedUser = user.getName(); if (optionalAuthCreds != null) { optionalAuthCreds.clear(); } Entry entry = null; String dn = null; EntryCursor result = null; EntryCursor rolesResult = null; LdapConnection ldapConnection = null; try { ldapConnection = getConnection(settings); final String bindDn = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_BIND_DN, null); if (bindDn != null) { ldapConnection.bind( bindDn, settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_PASSWORD, null)); } else { ldapConnection.anonymousBind(); } if (Dn.isValid(authenticatedUser)) { // assume dn log.trace("{} is a valid DN", authenticatedUser); entry = ldapConnection.lookup(authenticatedUser); if (entry == null) { throw new AuthException("No user '" + authenticatedUser + "' found"); } } else { // TODO FUTURE all ldap searches: follow referrals result = ldapConnection.search( settings.get(ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERBASE, ""), settings .get( ConfigConstants.ARMOR_AUTHENTICATION_LDAP_USERSEARCH, "(sAMAccountName={0})") .replace("{0}", authenticatedUser), SearchScope.SUBTREE); if (!result.next()) { throw new AuthException("No user '" + authenticatedUser + "' found"); } entry = result.get(); if (result.next()) { throw new AuthException("More than user found"); } } dn = entry.getDn().toString(); log.trace("User found with DN {}", dn); final Set<String> userRolesDn = new HashSet<String>(); // Roles as an attribute of the user entry // Role names may also be held as the values of an attribute in the user's directory entry. // Use userRoleName to specify the name of this attribute. final String userRoleName = settings.get( ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_USERROLENAME, "memberOf"); if (entry.get(userRoleName) != null) { final Value[] userRoles = Iterators.toArray(entry.get(userRoleName).iterator(), Value.class); for (int i = 0; i < userRoles.length; i++) { final Value value = userRoles[i]; final String possibleRoleDN = value.getString(); if (Dn.isValid(possibleRoleDN)) { userRolesDn.add(possibleRoleDN); } } log.trace("User roles count: {}", userRolesDn.size()); } final Map<Tuple<String, Dn>, Entry> roles = new HashMap<Tuple<String, Dn>, Entry>(); final String roleName = settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLENAME, "name"); // replace {2} final String userRoleAttribute = settings.get( ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_USERROLEATTRIBUTE, null); String userRoleAttributeValue = null; if (userRoleAttribute != null) { userRoleAttributeValue = entry.get(userRoleAttribute) == null ? null : entry.get(userRoleAttribute).getString(); } rolesResult = ldapConnection.search( settings.get(ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLEBASE, ""), settings .get( ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_ROLESEARCH, "(member={0})") .replace("{0}", dn) .replace("{1}", authenticatedUser) .replace("{2}", userRoleAttributeValue == null ? "{2}" : userRoleAttributeValue), SearchScope.SUBTREE); for (final Iterator iterator = rolesResult.iterator(); iterator.hasNext(); ) { final Entry searchResultEntry = (Entry) iterator.next(); roles.put( new Tuple<String, Dn>(searchResultEntry.getDn().toString(), searchResultEntry.getDn()), searchResultEntry); } log.trace("non user roles count: {}", roles.size()); for (final Iterator<String> it = userRolesDn.iterator(); it.hasNext(); ) { final String stringVal = it.next(); // lookup final Entry userRole = ldapConnection.lookup(stringVal); roles.put(new Tuple<String, Dn>(stringVal, null), userRole); } // nested roles if (settings.getAsBoolean( ConfigConstants.ARMOR_AUTHENTICATION_AUTHORIZATION_LDAP_RESOLVE_NESTED_ROLES, false)) { log.trace("Evaluate nested roles"); final Set<Entry> nestedReturn = new HashSet<Entry>(roles.values()); for (final Iterator<java.util.Map.Entry<Tuple<String, Dn>, Entry>> iterator = roles.entrySet().iterator(); iterator.hasNext(); ) { final java.util.Map.Entry<Tuple<String, Dn>, Entry> _entry = iterator.next(); final Set<Entry> x = resolveNestedRoles(_entry.getKey(), ldapConnection, roleName); log.trace("{}. nested roles for {} {}", x.size(), _entry.getKey(), roleName); nestedReturn.addAll(x); } for (final Iterator iterator = nestedReturn.iterator(); iterator.hasNext(); ) { final Entry entry2 = (Entry) iterator.next(); final String role = entry2.get(roleName).getString(); user.addRole(role); } if (user instanceof LdapUser) { ((LdapUser) user).addRoleEntries(nestedReturn); } } else { for (final Iterator iterator = roles.values().iterator(); iterator.hasNext(); ) { final Entry entry2 = (Entry) iterator.next(); final String role = entry2.get(roleName).getString(); user.addRole(role); } if (user instanceof LdapUser) { ((LdapUser) user).addRoleEntries(roles.values()); } } } catch (final Exception e) { log.error(e.toString(), e); throw new AuthException(e); } finally { if (result != null) { result.close(); } if (rolesResult != null) { rolesResult.close(); } SecurityUtil.unbindAndCloseSilently(ldapConnection); } }