Spring Security supporta la gestione di più provider di autenticazione. La classe AuthenticationManagerBuilder consente di implementare e gestire simultaneamente più meccanismi di autenticazione basati per esempio su LDAP e Active Directory oppure con credenziali memorizzate su Database o direttamente In-Memory. È inoltre possibile utilizzare gli oggetti AuthenticationProvider e UserDetails per estendere le proprietà di default dell’utente (username e password) e creare provider di autenticazione personalizzati basati per esempio su chiamate a servizi remoti RESTful e SOAP.
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;
}
}
Italiano
Inglese
