I am not able to authenticate a user using LDAP. I have got following details:
URL=ldap://10.10.10.10:389
LDAP BASE:DC=lab2,DC=ins
LDAP Bind Account: CN=Ldap Bind,OU=Service Accounts,OU=TECH,DC=lab2,DC=ins
LDAP Bind Account Pw: secret
I can search a sAMAccountName
value using above details, but how to authenticate a user with user name and password?
If you follow my previous questions then you will understand that, I am successfully able to connect to LDAP server but not able to authenticate him.
User to authenticate:
user: someusername
password: somepwd
I am not able to connect to LDAP server with 'somepwd'
and how should I use someusername
. I am able to search given user as sAMAccountName
.
This is a mashup of stuff I found in various places. It should put you along the correct path if you don't want to use the UnboundID SDK. This isn't production quality, you might want to add the SSL stuff in here if your shop supports it.
public static Boolean validateLogin(String userName, String userPassword) {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN);
// To get rid of the PartialResultException when using Active Directory
env.put(Context.REFERRAL, "follow");
// Needed for the Bind (User Authorized to Query the LDAP server)
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, LDAP_BIND_DN);
env.put(Context.SECURITY_CREDENTIALS, LDAP_BIND_PASSWORD);
DirContext ctx;
try {
ctx = new InitialDirContext(env);
} catch (NamingException e) {
throw new RuntimeException(e);
}
NamingEnumeration<SearchResult> results = null;
try {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Search Entire Subtree
controls.setCountLimit(1); //Sets the maximum number of entries to be returned as a result of the search
controls.setTimeLimit(5000); // Sets the time limit of these SearchControls in milliseconds
String searchString = "(&(objectCategory=user)(sAMAccountName=" + userName + "))";
results = ctx.search("", searchString, controls);
if (results.hasMore()) {
SearchResult result = (SearchResult) results.next();
Attributes attrs = result.getAttributes();
Attribute dnAttr = attrs.get("distinguishedName");
String dn = (String) dnAttr.get();
// User Exists, Validate the Password
env.put(Context.SECURITY_PRINCIPAL, dn);
env.put(Context.SECURITY_CREDENTIALS, userPassword);
new InitialDirContext(env); // Exception will be thrown on Invalid case
return true;
}
else
return false;
} catch (AuthenticationException e) { // Invalid Login
return false;
} catch (NameNotFoundException e) { // The base context was not found.
return false;
} catch (SizeLimitExceededException e) {
throw new RuntimeException("LDAP Query Limit Exceeded, adjust the query to bring back less records", e);
} catch (NamingException e) {
throw new RuntimeException(e);
} finally {
if (results != null) {
try { results.close(); } catch (Exception e) { /* Do Nothing */ }
}
if (ctx != null) {
try { ctx.close(); } catch (Exception e) { /* Do Nothing */ }
}
}
}
An LDAP connection starts off as anonymous
. To change the authorization state of a connection, use the BIND request. The BIND request takes two forms, 'simple' or 'SASL'. The 'simple' BIND request takes a distinguished name and password. The BIND request should be transmitted over a secure connection, or a non-secure connection promoted to a secure connection using the StartTLS
extended request.
Using the UnboundID LDAP SDK:
// exception handling not shown
LDAPConnection ldapConnection = new LDAPConnection(hostname,port);
BindRequest bindRequest = new SimpleBindRequest(username,password);
BindResult bindResult = ldapConnection.bind(bindRequest);
if(bindResult.getResultCode().equals(ResultCode.SUCCESS)) {
/// successful authentication
}
ldapConnection.close();
We have several JNDI Samples That might help.
Try using this, it worked for me
public static Boolean validateLogin(String userName, String userPassword) {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, userName + "@" + LDAP_SERVER);
env.put(Context.SECURITY_CREDENTIALS, userPassword);
DirContext ctx;
try {
ctx = new InitialDirContext(env); //throw exception, if username-password not correct
return true;
} catch (Exception e) {
return false;
}
}
来源:https://stackoverflow.com/questions/12163947/ldap-how-to-authenticate-user-with-connection-details