SpringBoot, how to Authenticate with LDAP without using ldif?
Solution 1
this one has worked perfectly for me but I need to make tiny modifications to it.
@Configuration
@EnableWebSecurity
public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(ldapAuthenticationProvider());
}
@Bean
public AuthenticationProvider ldapAuthenticationProvider() throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
Arrays.asList("ldapServerUrl:port"),rootDn);
contextSource.afterPropertiesSet();
LdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(ldapUserSearchBase, ldapUserSearchFilter, contextSource);
BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
bindAuthenticator.setUserSearch(ldapUserSearch);
LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator, new DefaultLdapAuthoritiesPopulator(contextSource, ldapGroupSearchBase));
return ldapAuthenticationProvider;
}
}
I have suffered for days before getting to this point Other wise you can use custom authentication and make the like this
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private Logger log = Logger.getLogger(CustomAuthenticationProvider.class);
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String email = authentication.getName();
String password = authentication.getCredentials().toString();
log.info("email : " + email);
log.info("password : " + password);
try {
if (authenticate(email, password)) {
// use the credentials
// and authenticate against the third-party system
return new UsernamePasswordAuthenticationToken(
email, password, new ArrayList<>());
} else {
return null;
}
} catch (NamingException ex) {
log.info(ex);
}
return null;
}
boolean isLdapRegistred(String username, String password) {
boolean result = false;
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://10.x.x.x:389");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "OUR-DOMAIN\\" + username);
env.put(Context.SECURITY_CREDENTIALS, password);
// Create the initial context
DirContext ctx = new InitialDirContext(env);
result = ctx != null;
if (ctx != null)
ctx.close();
System.out.println(result);
return result;
} catch (Exception e) {
System.out.println("oops");
return result;
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(
UsernamePasswordAuthenticationToken.class);
}
}
and on another class
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private Logger log = Logger.getLogger(WebSecurityConfiguration.class);
@Autowired
private CustomAuthenticationProvider authProvider;
@Override
protected void configure(
AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
}
Then the magic happens
Solution 2
Without LDIF, and using Spring, you can do something like:
@Configuration
@EnableWebSecurity
public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(ldapAuthenticationProvider());
}
@Bean
public AuthenticationProvider ldapAuthenticationProvider() throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapServerUrl);
contextSource.setUserDn(ldapManagerDn);
contextSource.setPassword(ldapManagerPassword);
contextSource.afterPropertiesSet();
LdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(ldapUserSearchBase, ldapUserSearchFilter, contextSource);
BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
bindAuthenticator.setUserSearch(ldapUserSearch);
LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator, new DefaultLdapAuthoritiesPopulator(contextSource, ldapGroupSearchBase));
return ldapAuthenticationProvider;
}
}
Related videos on Youtube
TwoThumbSticks
Codemonkey by day Ninja Programmer for a startup company by Night
Updated on September 15, 2022Comments
-
TwoThumbSticks over 1 year
I am trying out the LDAP Authentication example in SpringBoot here
It is using the ldif approach which I think is not applicable to my requirements because our ldap admin wont tell me where to find the ldif that I need. Before springboot I used to use my own ldap implementation not using ldif. Is there a way to validate not using ldif just the SECURITY_AUTHENTICATION.simple ? Below is how I do ldap security in basic Java no spring. How do I do this in spring without using ldif just basic username password.
boolean isLdapRegistred(String username, String password) { boolean result = false; 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://10.x.x.x:389"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "OUR-DOMAIN\\" + username); env.put(Context.SECURITY_CREDENTIALS, password); // Create the initial context DirContext ctx = new InitialDirContext(env); result = ctx != null; if (ctx != null) ctx.close(); System.out.println(result); return result; } catch (Exception e) { System.out.println("oops"); return result; } }
Below is SpringBoots example need to use my credentials instead of ldif.
@Configuration protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter { @Override public void init(AuthenticationManagerBuilder auth) throws Exception { auth .ldapAuthentication() .userDnPatterns("uid={0},ou=people") .groupSearchBase("ou=groups") .contextSource().ldif("classpath:test-server.ldif"); } }
-
danieltc07 about 3 yearsthanks, worked for me changing "if (authenticate(email, password)) " to "(isLdapRegistred(email, password))"