How to achieve Ldap authentication using spring security (spring boot)
I have a code with me I am trying to achieve ldap authentication but I think it is not happening.
Security configuration
@EnableWebSecurity
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().authorizeRequests().antMatchers("/*")
.permitAll().anyRequest().authenticated().and().csrf()
.disable().httpBasic().and().csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.ldapAuthentication()
.userSearchFilter("(uid={0})")
.userSearchBase("dc=intern,dc=xyz,dc=com")
.contextSource()
.url("ldap://192.168.11.11:1234/dc=intern,dc=xyz,dc=com")
.managerDn("username")
.managerPassword("password!")
.and()
.groupSearchFilter("(&(objectClass=user)(sAMAccountName=" + "username" + "))");
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request
.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
response.sendRedirect("/notAllowed");
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
My controller
@RequestMapping(value = { "/test" }, method = RequestMethod.GET)
public @ResponseBody String retrieve() {
System.out.println("line 1");
System.out.println("line 2");
return "hello";
}
@RequestMapping(value = { "/notAllowed" }, method = RequestMethod.GET)
public @ResponseBody HttpStatus login() {
return HttpStatus.FORBIDDEN;
}
I am targeting:
I want to do ldap authentication . U username and password will come from browser , although I also tried with hardcoded username and password.
if the user is authentic , then the filter checks the authorization by checking the token .
if this is the first request , then a new token will be generated and sent. if not found , it will send HTTP Disabled status .
I have the following problems:
-
when i run the first time from the browser it returns a ban, but it also outputs the lines "line 1 and line 2" in the console, although it does not return hi but it is forbidden.
-
Are my htpSecurity and ldap settings ok ?.
-
from the second request it always returns hi, I tried to open a new tab, new request, but it still works fine. If I restart the server , then only it generates the token and compare it with the cookie token. If two people use the same system (at different times).
-
how exactly can I check for ldap authentication? I am using POSTMAN as a client.
If any information is missing from my end, please let me know. And I will be grateful for your answers.
source to share
First of all, I think your HttpSecurity configurator is wrong. You want to protect ALL endpoints. Is not it?
So, change it to the following:
http.httpBasic()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
Also, I'm not sure if your ldap config is correct. I think you can reduce it to the following:
auth.ldapAuthentication()
.userSearchFilter("uid={0}")
.contextSource()
.url("ldap://192.168.11.11:1234/dc=intern,dc=xyz,dc=com");
Make sure your userSearchBase is right. It doesn't have "ou".
If you don't have different OUs, you can simply delete userSearchBase
To provide better help, I need to know the structure of your ldap.
If you want to check your HttpSecurity configuration, you can choose not to use ldap in the first place and use inMemoryAuthentication instead:
auth.inMemoryAuthentication().withUser("user").password("password").authorities("ROLE_USER");
source to share