I implemented database authentication for my web page and web service. It work well for both, now I have to add Ldap authentication. I have to authenticate through remote L
I also found this chapter Spring Docu Custom Authenicator and build my own switch between LDAP and my DB users. I can effortlessy switch between login data with set priorities (in my case LDAP wins).
I have configured an LDAP with the yaml configuration files for the LDAP user data which I don't disclose here in detail. This can be easily done with this Spring Docu LDAP Configuration.
I stripped the following example off the clatter such as logger/javadoc etc. to highlight the important parts. The @Order
annotation determines the priorities in which the login data is used. The in memory details are hardcoded debug users for dev only purposes.
SecurityWebConfiguration
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
private Environment env;
@Inject
private LdapConfiguration ldapConfiguration;
@Inject
private BaseLdapPathContextSource contextSource;
@Inject
private UserDetailsContextMapper userDetailsContextMapper;
@Inject
private DBAuthenticationProvider dbLogin;
@Inject
@Order(10) // the lowest number wins and is used first
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new InMemoryUserDetailsManager(getInMemoryUserDetails()));
}
@Inject
@Order(11) // the lowest number wins and is used first
public void configureLDAP(AuthenticationManagerBuilder auth) throws Exception {
if (ldapConfiguration.isLdapEnabled()) {
auth.ldapAuthentication().userSearchBase(ldapConfiguration.getUserSearchBase())
.userSearchFilter(ldapConfiguration.getUserSearchFilter())
.groupSearchBase(ldapConfiguration.getGroupSearchBase()).contextSource(contextSource)
.userDetailsContextMapper(userDetailsContextMapper);
}
}
@Inject
@Order(12) // the lowest number wins and is used first
public void configureDB(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(dbLogin);
}
}
DB Authenticator
@Component
public class DBAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
// your code to compare to your DB
}
@Override
public boolean supports(Class> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
/**
* @param original mandatory - input to be hashed with SHA256 and HEX encoding
* @return the hashed input
*/
private String sha256(String original) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new AuthException("The processing of your password failed. Contact support.");
}
if (false == Strings.isNullOrEmpty(original)) {
md.update(original.getBytes());
}
byte[] digest = md.digest();
return new String(Hex.encodeHexString(digest));
}
private class AuthException extends AuthenticationException {
public AuthException(final String msg) {
super(msg);
}
}
}
Feel free to ask details. I hope this is useful for someone else :D