User logs in with the user id which is the samaccountname. How do I authenticate the user id through active directory using ldap when i dont know the full distinguised namejust the samaccountname (JAVA).
This is how my code is:
public class LoginClass {
public static void main(String args[]){
boolean b= false;
Scanner scan = new Scanner(System.in);
System.out.println("Enter username : ");
String username = scan.next();
System.out.println("Enter password : ");
String password = scan.next();
Hashtable<String, Object> env = new Hashtable<String, Object>(11);
env
.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389");
// Authenticate as S. User and give incorrect password
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL,
"cn="+username+", cn=Users, dc=server,dc=domain");
env.put(Context.SECURITY_CREDENTIALS, password);
try {
System.out.println(env);
// Create initial context
DirContext ctx = new InitialDirContext(env);
b=true;
// Close the context when we're done
ctx.close();
} catch (NamingException e) {
b=false;
}
finally{
if(b==true){
System.out.println("Login Successful");
}
else{
System.out.println("Login Failed");
}
}
}
}
Related
I am new to LDAP. And I did the authentication part using LDAP INITIAL_CONTEXT_FACTORY ("com.sun.jndi.ldap.LdapCtxFactory"). Code of what I did is as follows.
String url = ldap_url;
String uname = request.getUsername();
String pwd = request.getPassword();
boolean authentication = false;
boolean error = true;
String msg, attributes, search;
String ldapDn = String.format("%s%s", searchFilter,uname);
// create env for initial context
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, ldapDn);
env.put(Context.SECURITY_CREDENTIALS, pwd);
try {
DirContext ctx = new InitialDirContext(env);
authentication = true;
error = false;
ctx.close();
} catch (Exception e) {
} finally {
if (!error) {
msg = "Login success!!!";
} else {
msg = "Authentication failed!";
}
}
Now I need to fetch the "employee_id" which returns with the LDAP result. I went through few examples in the internet and I could not make it happen. It will be great if anyone can suggest me a better way to search this attribute.
I'm trying to do an LDAP authentication using Java but this always return a null result and usrNamespace. Also was able to confirm that the username and password passed are correct.
With the username I use cn, i tried changing (uid=" + username + ") to cn but still gives me the same result
If anyone can help me that would be greatly appreciated. Thank you!
public class LdapAuthenticationAdapter implements AuthenticationAdapter {
#Override
public boolean authenticate(String username, String password) throws Exception {
Properties prop = new Properties();
//set the property value
SECURITY_AUTHENTICATION = prop.getProperty("eq.SECURITY_AUTHENTICATION");
SECURITY_PRINCIPAL = prop.getProperty("eq.SECURITY_PRINCIPAL");
SECURITY_CREDENTIALS = prop.getProperty("eq.SECURITY_CREDENTIALS");
PROVIDER_URL = prop.getProperty("eq.PROVIDER_URL");
// Get admin user, password(encrypted), host, port and other LDAP parameters
// from equationConfiguration.properties
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
env.put(Context.SECURITY_CREDENTIALS, "secret");
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:10389/dc=main,dc=com");
// env.put("java.naming.ldap.attributes.binary", "objectSID"); // validate this line if applicable
InitialDirContext context = new InitialDirContext(env);
SearchControls ctrls = new SearchControls();
ctrls.setReturningAttributes(new String[] { "givenName", "sn","memberOf" });
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<javax.naming.directory.SearchResult> answers = null;
SearchResult result = null;
String usrNamespace = null;
try {
answers = context.search("ou=bankfusionusers", "(uid=" + username + ")", ctrls); // Get directory context
result = answers.nextElement();
usrNamespace = result.getNameInNamespace();
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, "ldap://localhost:10389/dc=main,dc=com");
props.put(Context.SECURITY_PRINCIPAL, usrNamespace);
props.put(Context.SECURITY_CREDENTIALS, password);
System.err.println("Entry 1");
context = new InitialDirContext(props);
}catch(NullPointerException e){
System.err.println("Unsuccessful authenticated bind " + e + "\n");
return false;
}
return true;
}//end method
}
I changed your code a little bit, and it works on mine.
public static void main(String[] args) throws NamingException {
Properties initialProperties = new Properties();
initialProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
initialProperties.put(Context.PROVIDER_URL, "ldap://192.168.0.179:389");
initialProperties.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
initialProperties.put(Context.SECURITY_CREDENTIALS, "dirmanager");
initialProperties.put(Context.SECURITY_AUTHENTICATION, "simple");
InitialDirContext context = new InitialDirContext(initialProperties);
SearchControls ctrls = new SearchControls();
ctrls.setReturningAttributes(new String[] { "cn", "sn","givenname" });
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<javax.naming.directory.SearchResult> answers = null;
SearchResult result = null;
String usrNamespace = null;
try {
String username = "user.997"; // I added this, I removed some of your code as well
answers = context.search("dc=example,dc=com", "(uid=" + username + ")", ctrls); // Get directory context
result = answers.nextElement();
usrNamespace = result.getNameInNamespace();
System.out.println("result variable shows : " + result);
System.out.println("usrNamespace variable shows: " + usrNamespace);
}catch(NullPointerException e){
System.err.println("Unsuccessful authenticated bind " + e + "\n");
}
}
}
In my console, I see
I'm having some troubles with Spring security and Adam Ldap.
Here you can see my post without useful answer.
I thought to use my authenticate java code to set spring environment. This is my java code:
#Override
public void isAuthenticated(String username, String password) throws LdapException{
if (databaseMatlabClientServices.getByUsersEnabled(username)== null)
throw new LdapException("User doesn't exist into DART database. Please contact the administrator!");
String dn="";;
//First query to retriev DN
Hashtable<String, Object> ldapEnv = new Hashtable<String, Object>();
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
//Without authentication ldapEnv.put(Context.SECURITY_AUTHENTICATION, "none");
//With authentication to access to LDAP server
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, env.getRequiredProperty(PROPERTY_NAME_LDAP_NAME));
ldapEnv.put(Context.SECURITY_CREDENTIALS, env.getRequiredProperty(PROPERTY_NAME_LDAP_PASSWORD));
String[] returnAttribute = {"dn"};
DirContext ctx = null;
NamingEnumeration<SearchResult> results = null;
try {
ctx = new InitialDirContext(ldapEnv);
SearchControls controls = new SearchControls();
controls.setReturningAttributes(returnAttribute);
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// without authentication on local server String filter = "uid=" + username ;
String filter = "CN=" + username ;
results = ctx.search(env.getRequiredProperty(PROPERTY_NAME_LDAP_USERSEARCHBASE), filter, controls);
if (results.hasMore())
dn = results.nextElement().getNameInNamespace();
else
throw new LdapException("Wrong username. Please retry!");
} catch (NamingException e) {
throw new LdapException(e);
} finally {
try{
if (results != null)
results.close();
if (ctx != null)
ctx.close();
}catch(Exception e){
throw new LdapException(e);
}
}
//Second query to try to access with obtained Dn and given password
Hashtable<String, Object> authEnv = new Hashtable<String, Object>();
authEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
authEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
authEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
authEnv.put(Context.SECURITY_PRINCIPAL, dn);
authEnv.put(Context.SECURITY_CREDENTIALS, password);
DirContext ctx2 = null;
try {
ctx2 = new InitialDirContext(authEnv);
} catch (AuthenticationException authEx) {
throw new LdapException("Authentication error. Password was wrong");
} catch(Exception e){
throw new LdapException(e);
}finally {
try{
if (ctx2 != null)
ctx2.close();
}catch(Exception e){
throw new LdapException(e);
}
}
}
This code recognize if user and password exists on Ldap System.
In Spring I have
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldaps://vdap.floal:636/");
contextSource.setBase("DC=fg,DC=local");
contextSource.setReferral("follow");
contextSource.setUserDn("CN=A00XXX32,CN=Administration,CN=fdam,DC=fg,DC=local");
contextSource.setPassword(password);
contextSource.afterPropertiesSet();
LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> ldapAuthenticationProviderConfigurer = auth.ldapAuthentication();
ldapAuthenticationProviderConfigurer
.contextSource(contextSource)
.userSearchBase("CN=fdam")
.userSearchFilter(env.getRequiredProperty("(CN={0})"))
.ldapAuthoritiesPopulator(myAuthPopulator);
}
and my authorities populator to give role information from database
#Service("myAuthPopulator")
public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {
#Autowired
private UserServices userServices;
static final Logger LOG = LoggerFactory.getLogger(MyAuthoritiesPopulator.class);
#Transactional(readOnly=true)
#Override
public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
try{
com.domain.User user = userServices.getByUsersEnabled(username);
if (user==null){
LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : User doesn't exist into DART database" );
}
else{
//Use this if a user can have different roles
// for(Role role : user.getRole()) {
// authorities.add(new SimpleGrantedAuthority(role.getRole()));
// }
authorities.add(new SimpleGrantedAuthority(user.getRole().getRole()));
return authorities;
}
}catch(Exception e){
LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : " + ErrorExceptionBuilder.buildErrorResponse(e)); }
return authorities;
}
}
Is it possible to merge these two strategy to fix my problem with Ldap authentication, so use java code to set Spring? Thanks
I want to query my ldap to give me all users where sn contains a specific value (maier). However I always get a single result.
public LdapContext getLdapContext(){
LdapContext ctx = null;
try{
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.url:389");
ctx = new InitialLdapContext(env, null);
System.out.println("Connection Successful.");
}catch(NamingException nex){
System.out.println("LDAP Connection: FAILED");
nex.printStackTrace();
}
return ctx;
}
private User getUserBasicAttributes(String username, LdapContext ctx) {
User user=null;
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = { "distinguishedName",
"sn",
"givenname",
"mail",
"telephonenumber"};
constraints.setReturningAttributes(attrIDs);
constraints.setCountLimit(200);
NamingEnumeration answer = ctx.search("DC=myDc,DC=com", "sn=*maier*", constraints);
if (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
System.out.println("distinguishedName "+ attrs.get("distinguishedName"));
System.out.println("givenname "+ attrs.get("givenname"));
System.out.println("sn "+ attrs.get("sn"));
System.out.println("mail "+ attrs.get("mail"));
System.out.println("telephonenumber "+ attrs.get("telephonenumber"));
}else{
throw new Exception("Invalid User");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return user;
}
Did I do anything wrong?
You're not looping, so of course you're only getting one result. Change if (answer.hasMore()) to while (answer.hasMore()).
I have a problem adding an entry in LDAP, precisely I want to add a user.
class AddUser {
public static void main(String[] args) {
String userName = "manager";
String password = "pass";
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://192.168.10.45:389/dc=mydc,dc=local");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, new String("mydc" + "\\" + userName));
env.put(Context.SECURITY_CREDENTIALS, password);
// env.put(Context.REFERRAL, "follow");
// entry's DN
String entryDN = "cn=NewUser, dc=mydc, dc=local";
// entry's attributes
Attribute cn = new BasicAttribute("cn", "NewUser");
Attribute sn = new BasicAttribute("sn", "Smith");
Attribute mail = new BasicAttribute("mail", "newuser#foo.com");
Attribute phone = new BasicAttribute("telephoneNumber", "+1 222 3334444");
Attribute uid = new BasicAttribute("uid", "nsmith");
Attribute userPassword = new BasicAttribute("userPassword", "pwd1");
Attribute oc = new BasicAttribute("objectClass");
oc.add("dcObject");
oc.add("person");
oc.add("inetOrgPerson");
DirContext ctx = null;
try {
// get a handle to an Initial DirContext
ctx = new InitialDirContext(env);
// build the entry
Attributes entry = new BasicAttributes();
entry.put(cn);
entry.put(sn);
entry.put(mail);
entry.put(phone);
entry.put(uid);
entry.put(userPassword);
entry.put(oc);
// Add the entry
ctx.createSubcontext(entryDN, entry);
System.out.println("AddUser: added entry " + entryDN + ".");
} catch (NamingException e) {
System.err.println("AddUser: error adding entry." + e);
}
}
}
I got the following error:
AddUser: error adding
entry.javax.naming.directory.NoSuchAttributeException: [LDAP: error code 16 - 00000057: LdapErr: DSID-0C090C3E, comment: Error in attribute conversion operation, data 0, v1db1 ]; remaining name cn=NewUser, dc=mydc, dc=local
I don't know where is the error. Can be only a bad input about the attributes?
The right code is the following:
public static void main(String[] args) {
String userName = "admin";
String password = "s3cret";
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://192.168.10.10:389/DC=SOFTWAREDEV,DC=LOCAL");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, new String("softwaredev" + "\\" + userName));
env.put(Context.SECURITY_CREDENTIALS, password);
String path = "OU=SoftwareV3,OU=SOFTWARE";
String newUser = "myUser"; // insert user here
String entryDN = "CN=" + newUser + "," + path;
Attribute cn = new BasicAttribute("cn", newUser);
Attribute oc = new BasicAttribute("objectClass");
oc.add("top");
oc.add("person");
oc.add("organizationalPerson");
oc.add("user");
DirContext ctx = null;
try {
ctx = new InitialDirContext(env);
Attributes entry = new BasicAttributes();
entry.put(cn);
entry.put(oc);
ctx.createSubcontext(entryDN, entry);
System.out.println("AddUser: added entry " + entryDN + ".");
} catch (NamingException e) {
System.err.println("AddUser: error adding entry." + e);
}
}