Fix LDAP search issue with VDS

This commit is contained in:
Mars Lan 2018-05-23 17:35:08 -07:00
parent 2a8058f3fc
commit e5fc1643b4
2 changed files with 16 additions and 14 deletions

View File

@ -24,6 +24,8 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import javax.naming.AuthenticationException;
import javax.naming.NamingException;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import play.data.DynamicForm; import play.data.DynamicForm;
@ -315,7 +317,7 @@ public class Application extends Controller {
} }
@BodyParser.Of(BodyParser.Json.class) @BodyParser.Of(BodyParser.Json.class)
public static Result authenticate() { public static Result authenticate() throws NamingException {
JsonNode json = request().body().asJson(); JsonNode json = request().body().asJson();
// Extract username and password as String from JsonNode, // Extract username and password as String from JsonNode,
// null if they are not strings // null if they are not strings
@ -341,9 +343,9 @@ public class Application extends Controller {
try { try {
AuthenticationManager.authenticateUser(username, password); AuthenticationManager.authenticateUser(username, password);
} catch (Exception e) { } catch (AuthenticationException e) {
Logger.warn("Authentication error!", e); Logger.warn("Authentication error!", e);
return badRequest(e.getMessage()); return badRequest("Invalid Credential");
} }
// Adds the username to the session cookie // Adds the username to the session cookie

View File

@ -14,6 +14,7 @@
package security; package security;
import dao.UserDAO; import dao.UserDAO;
import javax.naming.directory.SearchControls;
import wherehows.models.table.User; import wherehows.models.table.User;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import play.Logger; import play.Logger;
@ -30,9 +31,6 @@ import javax.naming.Context;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.NamingEnumeration; import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute; import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext; import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext; import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchResult; import javax.naming.directory.SearchResult;
@ -49,6 +47,8 @@ public class AuthenticationManager {
private static final String LDAP_MAIL_KEY = "mail"; private static final String LDAP_MAIL_KEY = "mail";
private static final String LDAP_DEPARTMENT_NUMBER_KEY = "departmentNumber"; private static final String LDAP_DEPARTMENT_NUMBER_KEY = "departmentNumber";
private static final String LDAP_USER_ATTR_FILTER_EXPRESSION = "(&(objectClass=user)(sAMAccountName={0}))";
private static final String contextFactories = private static final String contextFactories =
Play.application().configuration().getString(LDAP_CONTEXT_FACTORY_CLASS_KEY); Play.application().configuration().getString(LDAP_CONTEXT_FACTORY_CLASS_KEY);
/* three LDAP properties, each is a '|' separated string of same number of tokens. e.g. /* three LDAP properties, each is a '|' separated string of same number of tokens. e.g.
@ -63,7 +63,6 @@ public class AuthenticationManager {
private static final String[] ldapSearchBase = private static final String[] ldapSearchBase =
Play.application().configuration().getString(LDAP_SEARCH_BASE_KEY).split("\\s*\\|\\s*"); Play.application().configuration().getString(LDAP_SEARCH_BASE_KEY).split("\\s*\\|\\s*");
public static void authenticateUser(String userName, String password) throws NamingException { public static void authenticateUser(String userName, String password) throws NamingException {
if (userName == null || userName.isEmpty() || password == null || password.isEmpty()) { if (userName == null || userName.isEmpty() || password == null || password.isEmpty()) {
throw new IllegalArgumentException("Username and password can not be blank."); throw new IllegalArgumentException("Username and password can not be blank.");
@ -125,7 +124,7 @@ public class AuthenticationManager {
} }
private static Map<String, String> getUserAttributes(DirContext ctx, String searchBase, String userName, private static Map<String, String> getUserAttributes(DirContext ctx, String searchBase, String userName,
String principalDomain, String... attributeNames) throws NamingException { String... attributeNames) throws NamingException {
if (StringUtils.isBlank(userName)) { if (StringUtils.isBlank(userName)) {
throw new IllegalArgumentException("Username and password can not be blank."); throw new IllegalArgumentException("Username and password can not be blank.");
} }
@ -134,11 +133,12 @@ public class AuthenticationManager {
return Collections.emptyMap(); return Collections.emptyMap();
} }
Attributes matchAttr = new BasicAttributes(true); SearchControls searchControls = new SearchControls();
BasicAttribute basicAttr = new BasicAttribute("userPrincipalName", userName + principalDomain); searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
matchAttr.put(basicAttr); searchControls.setReturningAttributes(attributeNames);
NamingEnumeration<? extends SearchResult> searchResult = ctx.search(searchBase, matchAttr, attributeNames); NamingEnumeration<? extends SearchResult> searchResult =
ctx.search(searchBase, LDAP_USER_ATTR_FILTER_EXPRESSION, new Object[]{userName}, searchControls);
Map<String, String> result = new HashMap<>(); Map<String, String> result = new HashMap<>();
if (searchResult.hasMore()) { if (searchResult.hasMore()) {
@ -158,8 +158,8 @@ public class AuthenticationManager {
private static User getAttributes(DirContext ctx, String searchBase, String userName, String principalDomain) private static User getAttributes(DirContext ctx, String searchBase, String userName, String principalDomain)
throws NamingException { throws NamingException {
Map<String, String> userDetailMap = Map<String, String> userDetailMap =
getUserAttributes(ctx, searchBase, userName, principalDomain, LDAP_DISPLAY_NAME_KEY, LDAP_MAIL_KEY, getUserAttributes(ctx, searchBase, userName, LDAP_DISPLAY_NAME_KEY, LDAP_MAIL_KEY, LDAP_DEPARTMENT_NUMBER_KEY);
LDAP_DEPARTMENT_NUMBER_KEY); Logger.info("userDetailMap: " + userDetailMap);
String displayName = userDetailMap.get(LDAP_DISPLAY_NAME_KEY); String displayName = userDetailMap.get(LDAP_DISPLAY_NAME_KEY);
String[] displayNameTokens = displayName.trim().replaceAll(" +", " ").split(" "); String[] displayNameTokens = displayName.trim().replaceAll(" +", " ").split(" ");