-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
login: Support simplified LDAP login
- Loading branch information
Showing
6 changed files
with
247 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* Yona, 21st Century Project Hosting SW | ||
* <p> | ||
* Copyright Yona & Yobi Authors & NAVER Corp. | ||
* https://yona.io | ||
**/ | ||
package models.support; | ||
|
||
import javax.naming.NamingException; | ||
import javax.naming.directory.Attribute; | ||
|
||
public class LdapUser { | ||
private Attribute displayName; | ||
private Attribute email; | ||
private Attribute userLoginId; | ||
private Attribute department; | ||
|
||
public LdapUser(Attribute displayName, Attribute email, Attribute userLoginId, Attribute department) { | ||
this.displayName = displayName; | ||
this.email = email; | ||
this.userLoginId = userLoginId; | ||
this.department = department; | ||
} | ||
|
||
public String getDisplayName() { | ||
return getString(this.displayName); | ||
} | ||
|
||
private String getString(Attribute attr) { | ||
try { | ||
if (attr.get() == null){ | ||
return ""; | ||
} else { | ||
return attr.get().toString(); | ||
} | ||
} catch (NamingException e) { | ||
e.printStackTrace(); | ||
return ""; | ||
} | ||
} | ||
|
||
public String getEmail() { | ||
return getString(email); | ||
} | ||
|
||
public String getUserLoginId() { | ||
return getString(userLoginId); | ||
} | ||
|
||
public String getDepartment() { | ||
return getString(department); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "LdapUser{" + | ||
"displayName='" + getDisplayName() + '\'' + | ||
", email='" + getEmail() + '\'' + | ||
", userId='" + getUserLoginId() + '\'' + | ||
", department='" + getDepartment() + '\'' + | ||
'}'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* Yona, 21st Century Project Hosting SW | ||
* <p> | ||
* Copyright Yona & Yobi Authors & NAVER Corp. | ||
* https://yona.io | ||
**/ | ||
package utils; | ||
|
||
import models.support.LdapUser; | ||
import play.Play; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.naming.Context; | ||
import javax.naming.NamingEnumeration; | ||
import javax.naming.NamingException; | ||
import javax.naming.directory.*; | ||
import java.util.Hashtable; | ||
|
||
public class LdapService { | ||
public static final boolean useLdap = Play.application().configuration().getBoolean("application.use.ldap.login.supoort",false); | ||
private static final String HOST = Play.application().configuration().getString("ldap.host", "127.0.0.1"); | ||
private static final String PORT = Play.application().configuration().getString("ldap.port", "389"); | ||
private static final String BASE_DN = Play.application().configuration().getString("ldap.baseDN", ""); | ||
private static final String DN_POSTFIX = Play.application().configuration().getString("ldap.distinguishedNamePostfix", ""); | ||
private static final String PROTOCOL = Play.application().configuration().getString("protocol", "ldap"); | ||
private static final int TIMEOUT = 5000; //ms | ||
|
||
public LdapUser authenticate(String username, String password) throws NamingException { | ||
|
||
Hashtable<String, String> env = new Hashtable<>(); | ||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); | ||
env.put("com.sun.jndi.ldap.connect.timeout", ""+(TIMEOUT)); | ||
env.put(Context.PROVIDER_URL, PROTOCOL + "://" + HOST + ":" + PORT); | ||
env.put(Context.SECURITY_AUTHENTICATION, "simple"); | ||
env.put(Context.SECURITY_PRINCIPAL, getProperUsernameGuessing(username)); | ||
env.put(Context.SECURITY_CREDENTIALS, password); | ||
|
||
DirContext authContext = new InitialDirContext(env); | ||
SearchResult searchResult = findUser(authContext, username, searchFilter(username)); | ||
if (searchResult != null) { | ||
return getLdapUser(searchResult); | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
private LdapUser getLdapUser(SearchResult searchResult) throws NamingException { | ||
Attributes attr = searchResult.getAttributes(); | ||
return new LdapUser(attr.get("displayName"), | ||
attr.get("mail"), | ||
attr.get("sAMAccountName"), | ||
attr.get("department")); | ||
} | ||
|
||
private String searchFilter(@Nonnull String username) { | ||
if(username.contains("@")){ | ||
return "mail"; | ||
} else { | ||
return "sAMAccountName"; | ||
} | ||
} | ||
|
||
private String getProperUsernameGuessing(@Nonnull String username){ | ||
if(username.contains("@")){ | ||
return username; | ||
} else { | ||
return "CN=" + username + ", " + DN_POSTFIX; | ||
} | ||
} | ||
|
||
private SearchResult findUser(DirContext ctx, String username, String filter) throws NamingException { | ||
|
||
String searchFilter = "(&(objectClass=user)(" + filter + "=" + username + "))"; | ||
|
||
SearchControls searchControls = new SearchControls(); | ||
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); | ||
|
||
NamingEnumeration<SearchResult> results = ctx.search(BASE_DN, searchFilter, searchControls); | ||
|
||
SearchResult searchResult = null; | ||
if(results.hasMoreElements()) { | ||
searchResult = (SearchResult) results.nextElement(); | ||
|
||
//make sure there is not another item available, there should be only 1 match | ||
if(results.hasMoreElements()) { | ||
System.err.println("Matched multiple users for the username: " + username); | ||
return null; | ||
} | ||
} | ||
|
||
return searchResult; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters