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