November 05, 2024

Multiple authentication provider in Spring Security

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

SOURCE CODE (/giuseu/spring-mvc)

GIT
git clone https://gitlab.com/giuseppeurso-eu/spring-mvc

 

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;

}

}

 

 

 

Related posts

Leave a Reply

Your email address will not be published.