Kuby Block

Blog about programming, tech, society and more.

Manually to create LDAP authentication provider

poster

Have you ever want to create a custom login flow with composite of ldap and other authentication? But you relize that, LDAP almost use integrated with Spring security? And you would like to use it seperatedly, yes, me too and now I will share you the way I have used.

1. Use class DefaultSpringSecurityContextSource to create LDAP context source.

It is a little weird that we will use DefaultSpringSecurityContextSource to create a LDAP context source. I have tried with LdapContextSource purely, but it is not working! So I switch to use DefaultSpringSecurityContextSource as source-code of integrated of Spring Security in ldapAuthentication() method :)


private LdapContextSource ldapContextSource() {
  final LdapContextSource ldapContextSource = new DefaultSpringSecurityContextSource("YOUR_URL_OF_LDAP");

  ldapContextSource.setBase("YOUR_BASE");
  ldapContextSource.setUserDn("YOUR_MANAGER_LDAP_USERNAME");
  ldapContextSource.setPassword("YOUR_MANAGER_LDAP_PASSWORD");
  ldapContextSource.setPooled(true);

  return ldapContextSource;
}

with YOUR_URL_OF_LDAP, sometimes you will need YOUR_URL_OF_LDAP\YOUR_BASE to get correct url.

2. Define a bean of LDAP Authentication Provider


@Bean
public LdapAuthenticationProvider ldapAuthenticationProvider() {
  // use from previous defined method
  final LdapContextSource ldapContextSource = ldapContextSource();
  final BindAuthenticator bindAuthenticator = new BindAuthenticator(ldapContextSource);

  bindAuthenticator.setUserSearch(new FilterBasedLdapUserSearch(
          "YOUR_SEARCH_BASE", // if null will search base on baseDn of ldapContextSource
          "LDAP_USER_SEARCH_PATTERN",
          ldapContextSource)
  ); // optional
  bindAuthenticator.setUserDnPatterns(new String[]{"USER_DN_PATTERN"}); // optional
  bindAuthenticator.setUserAttributes(new String[]{"ATTRIBUTE_TO_GET", "mail", "title"}); // optional

  final LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator);

  ldapAuthenticationProvider.setAuthoritiesMapper(username -> {
      return new ArrayList<>();
  }); // you also can custom for your authority mapper

  ldapAuthenticationProvider.setUserDetailsContextMapper(
          new InetOrgPersonContextMapper()
  ); // and you can map user by InetOrgPersonContextMapper to get more info of logon user by ldap

  return ldapAuthenticationProvider;
}

That’s Ok, and now, you can put 2 methods in the same class or anywhere you want with annotation @Configuration to help Spring Boot recognize and initialize it when start up.

3. Use it!

Assume that you created that bean completely, now we will use it in anywhere we want in Spring Boot context, in this case, UserServiceImpl


@Service
public class UserServiceImpl implements UserService {
  @Autowired
  private LdapAuthenticationProvider ldapAuthenticationProvider;

  @Override
  public boolean checkLogin(String username, String password){
    try {
      UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
      final Authentication resultAuthentication = ldapAuthenticationProvider.authenticate(authentication);

      // Some other logic, ex: business login, auth2,...

      return true; // or result after applied other logics
    }catch(Exception ex){
      logger.error(ex);
      return false;
    }
  }

}

Yeah, that’s all. Thanks for read the whole article!


comments powered by Disqus