Spring Boot Security

Authentication Components

The diagram below show the main components for authentication used in the Spring Boot Security framework and the relationship and interactions between these components.

../../_images/SpringSecurityComponents.png

The main components of the authentication process for Spring Security

  1. The login is intercepted by the authentication filter.

  2. Authentication responsibility is delegated to the authentication manager. Based on the response, it configures the security context.

  3. The authentication manager calls the authentication provider. The authentication provider implements the authentication logic. This implementation is in the user details service.

  4. The authentication provider locates the user with the user details service and validates the user’s password using a password encoder.

  5. The result of the authentication is returned to the authentication filter.

  6. Details of the authenticated entity are stored in the security context.

In a simple spring boot configuration, the implementation is carried out by the two auto configured beans UserDetailsService and Password Encoder. The AuthenticationProvider defines the authentication logic for user and password management. By default, it uses the UserDetailsService and Password Encoder.

The UserDetailsService and PasswordEncoder

An object that implements a UserDetailsService manages details about the users (List<UserDetails>) for the application. This service is only responsible for retrieving the user by username. When we define the UserDetailsService, we must also specify a PasswordEncoder.

The AuthenticationProvider defines the authentication logic, delegating user and password management to these functions.

See With Java Spring Boot Security on how to generate a PKCS12 public key certificate and configure a Java Spring Boot application to use it.

User Management

User Management allows us to add, modify and delete users in the UserDetailsService.

../../_images/SpringSecurityUserManagement.png

Components in Spring Boot Security User Management.

  1. The UserDetailsService uses the UserDetails interface contract and returns the details of a user, finding the user by his / her name. The UserDetails interface contract describes the user.

  2. The UserDetails has one or more authorities, represented by the GrantedAuthority interface.

  3. The UserDetailsManager extends the UserDetailsService, adding operations such as create, delete, or change password to the user.

Given below are the interface details for UserDetails.

public interface UserDetails extends Serializable {
  String getUsername();
  String getPassword();
  Collection<? extends GrantedAuthority> getAuthorities();
  boolean isAccountNonExpired();
  boolean isAccountNonLocked();
  boolean isCredentialsNonExpired();
  boolean isEnabled();
}

Authentication

Spring Boot’s Authentication contract extends the Java Security API’s Principal contract in the following manner:

public interface Authentication extends Principal, Serializable {
  Collection<? extends GrantedAuthority> getAuthorities();
  Object getCredentials();
  Object getDetails();
  Object getPrincipal();
  boolean isAuthenticated();
  void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
  • isAuthenticated(): Returns true if the authentication process has ended or false if authentication is still in progress.

  • getCredentials(): Returns a password or any secret used in the authentication process.

  • getAuthorities(): Returns a collection of granted authorities for the authentication request.

Spring Boot’s AuthenticationProvider is responsible for the authentication logic. It’s default implementation delegates finding the user to a UserDetailsService and PasswordEncoder for password management.
The definition of the AuthenticationProvider is given below:
public interface AuthenticationProvider {
  Authentication authenticate(Authentication authentication) throws AuthenticationException;
  boolean supports(Class<?> authentication);
}

If we implement / customise the AuthenticationProvider responsibility, the authenticate method needs to:

  • throw an AuthenticationException if authentication fails.

  • if it receives an authentication object that is not supported by our implementation, we should return a null. This ensures allowing multiple authentication mechanisms separated at the HTTP filter level.

  • return an Authentication instance representing a fully authenticated object.