Spring Security supports a wide range of authentication mechanisms. AuthenticationManagerBuilder object allows using multiple built-in authentication provider like In-Memory authentication, LDAP authentication, JDBC based authentication. In addition to its own set of authentication models, Spring Security allows to write your custom authentication mechanism to authenticate, for example, against a secure RESTful or SOAP remote API authentication service.
Stack
JDK 1.8
Maven 3.5.9
Spring Security 5.0.1.RELEASE
AuthenticationConfig
public class AuthenticationConfig extends WebSecurityConfigurerAdapter { // Settings and something else here // .... /** * Configures multiple Authentication providers. * AuthenticationManagerBuilder allows for easily building multiple authentication mechanisms in the order they're declared. */ @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { if (inMemoryAuthEnabled) { System.out.println(">>>>> [IN-MEMORY] Authentication Provider enabled: "+inMemoryAuthEnabled); auth.inMemoryAuthentication().withUser(inMemoryAuthUser).password(inMemoryAuthPasswd).roles("USER"); } if (ldapAuthEnabled) { System.out.println(">>>>> [LDAP] Authentication Provider enabled: "+ldapAuthEnabled); DefaultSpringSecurityContextSource ldapContextSource = new DefaultSpringSecurityContextSource(ldapAuthUrl+"/"+ldapAuthBaseDn); if (ldapAuthPrincipalUser!=null) { ldapContextSource.setUserDn(ldapAuthPrincipalUser); ldapContextSource.setPassword(ldapAuthPrincipalPasswd); System.out.println("Initializing LDAP Source with Principal '"+ldapAuthPrincipalUser+"/****'"); } ldapContextSource.afterPropertiesSet(); auth.ldapAuthentication() .userSearchBase(ldapUsersSearchBase) .userSearchFilter(ldapUsersSearchFilter) .groupSearchBase(ldapGroupsSearchBase) .groupSearchFilter(ldapGroupsSearchFilter) .contextSource(ldapContextSource); } if (adAuthEnabled) { System.out.println(">>>>> [ACTIVE DIRECTORY] Authentication Provider enabled: "+adAuthEnabled); ActiveDirectoryLdapAuthenticationProvider adSource = new ActiveDirectoryLdapAuthenticationProvider(adAuthDomain, adAuthUrl, adAuthBaseDn); adSource.setConvertSubErrorCodesToExceptions(true); adSource.setSearchFilter(adAuthUsersFilter); auth.authenticationProvider(adSource); } if (jdbcAuthEnabled) { System.out.println(">>>>> [JDBC] Authentication Provider enabled: "+jdbcAuthEnabled); auth.jdbcAuthentication().dataSource(dataSource) .usersByUsernameQuery(jdbcAuthQuery); } if (wsAuthEnabled) { System.out.println(">>>>> [REMOTE WEB SERVICE] Authentication Provider enabled: "+wsAuthEnabled); // Create your custom provider by implementing the AuthenticationProvider interface and set here the provider responsible for the external authentication. auth.authenticationProvider(wsAuthProvider); } } /** * Overrides the HttpSecurity configuration requests mapping. */ @Override protected void configure(HttpSecurity http) throws Exception { System.out.println("Restricting access to specific http requests..."); // Your code here... } }
MyCustomUserDetails
public class MyCustomUserDetails implements UserDetails{ private User user; private List<SimpleGrantedAuthority> authorities=null; // Custom User details private String address; private String email; /** * Getters and setters for the custom UserDetails * @return */ public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } /** * Getters and setters for the inherited attributes of the UserDetails object. */ // Overriding of the inherited user attributes //... }
MyCustomAuthProvider
public class MyCustomAuthProvider implements AuthenticationProvider{ /** * Use credentials coming from the login page and authenticate against a third-party system. */ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String password = authentication.getCredentials().toString(); UsernamePasswordAuthenticationToken userAuth = null; System.out.println("Use credentials [" + username + "|*****] and authenticate against the third-party system..."); // Put here your code for the remote authentication // Invoking the external authentication web service and make something with the response // ... String authenticationResponse = ""; if (authenticationResponse.equals("user authenticated or something else")) { System.out.println("Connection to External Authentication Web Service succeeded for user: "+username); List<SimpleGrantedAuthority> authorities=new ArrayList<SimpleGrantedAuthority>(); User user = new User(username, password, true, true, true, true, authorities); MyCustomUserDetails userDetails = new MyCustomUserDetails(); userDetails.setUser(user); userDetails.setAuthorities(authorities); System.out.println("Attaching some custom user details to the authenticated user..."); userDetails.setAddress("The user address or something else returned by the external authentication service."); userDetails.setEmail("The user email or something else returned by the external authentication service."); //userAuth = new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>()); userAuth = new UsernamePasswordAuthenticationToken(userDetails, password, new ArrayList<>()); }else { System.out.println("User ["+username+"] authentication failed! Wrong credentials or invalid account."); } return userAuth; } }