basics of spring security architecture

The Spring Security project is perhaps the biggest and one of the best projects so far by Spring. When I first started using this framework, I found it a bit difficult but actually it is quite easy to understand if we know the basics of spring security architecture.

In this post, I will provide a decent idea about the Spring Security architecture and the general flows, which will help you to use this library extensively.

Before starting the discussion, I would like to separate the Spring Security library into three parts –

  • Authentication
  • Authorization
  • Exceptions

Here, I am going to discuss the Authentication part.

What is Authentication ?

Authentication is validating the credentials like username and password. There are multiple ways of authentication. E.g. : Single Factor Authentication, Two Factor authentication and Multi Factor authentication.

How Spring Handles Authentication ?

Spring Security Framework has multiple filters through which it performs the authentication and other security measures. As, this article is all about Authentication, I will only touch the filters and flows which take active parts in authenticating an user.

The Spring Security Authentication Filter is the first and foremost filter which sits at the top and starts calling other services to perform the authentication process whenever it receives an HTTP Request having the Basic scheme of Username and Password.

Spring Security Authentication Filter

Typically, Spring Security Authentication Filter performs three operations. These are:

  1. Extraction of Username and Password from the HTTP Basic Scheme.
  2. Creates the Authentication Token using UsernamePasswordAuthenticationToken class provided by Spring Security.
  3. AuthenticationManager interface checks the authentication token and determines whether it is a valid credential, otherwise throws BadCredentialsException.

The below picture is a representation of how Spring Security Authentication Filter works.

flow of spring security authentication filter

Spring Security Authentication

My next dive will be into the UsernamePasswordAuthenticationToken class. How does it verifies whether the supplied credentials are matching and how come it says the user is authenticated ?

The Authentication Manager works based on delegation. It delegates all the authentication related operations to its one or more Authentication Providers (Which can be our own user store or a third party service).

flow of spring security authentication

The AuthenticationProvider is an interface having one method called authenticate(). All the Authentication Providers must implement this method and return an Object which is an implementation of the Authentication interface.

Below are the signatures of AuthenticationProvider and Authentication interfaces.

AuthenticationProvider Interface

public interface AuthenticationProvider {
    Authentication authenticate(Authentication var1) throws AuthenticationException;

    boolean supports(Class<?> var1);
}

Authentication Interface

public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    Object getCredentials();

    Object getDetails();

    Object getPrincipal();

    boolean isAuthenticated();

    void setAuthenticated(boolean var1) throws IllegalArgumentException;
}

Spring Security User Details Service

We have understood that the Authentication Manager returns the User Details by using its Authentication Providers. Now, we will be having a dive into the Authentication Providers and how it fetches the User Details.

Typically, AuthenticationProvider needs two things –

  • Implementation of the UserDetailsService interface which has a method called loadUserByUsername().
  • A PasswordEncoder.

The loadUserByUsername() method should be implemented by us with our own logic and ways to retrieve the user including the username and password and should return an object which should implement UserDetails interface.

Below are the signatures of these two interfaces –

UserDetailsService Interface

public interface UserDetailsService {
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

UserDetails Interface

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword();

    String getUsername();

    boolean isAccountNonExpired();

    boolean isAccountNonLocked();

    boolean isCredentialsNonExpired();

    boolean isEnabled();
}

The PasswordEncoder checks if the returned encoded password from our user store (which was encoded using the same password encoder library during the creation of the user) matches with the supplied user credentials. An example of Spring’s own password encoder is BCryptPasswordEncoder. We can write our own encoder too, which must implement the below PasswordEncoder interface.

public interface PasswordEncoder {
    String encode(CharSequence var1);

    boolean matches(CharSequence var1, String var2);

    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}

If everything works file. It returns that the User is authenticated with all the user details supplied by the Authentication Provider through User Details Service.

Here is a representation of the whole process – how the Authentication Manager consults with the Authentication Provider to get the User Details.

flow of spring security user details service

Spring Security Context Holder

The final step that Spring Security architecture focuses is to take care about the users who are currently logged in. To perform this functionality, Spring has come up with a concept of SecurityContextHolder. It uses a ThreadLocal object named SecurityContext to hold the Authentication. This means, the SecurityContext is always available to the methods for the current thread of execution, even if we don’t pass the authentication object every time.

public interface SecurityContext extends Serializable {
    Authentication getAuthentication();
    void setAuthentication(Authentication var1);
}

Although, there are multiple strategies provided by Spring to store the SecurityContext, but by default, it is a ThreadLocal object.

Also, at the time of logging out, Spring Security has its own way to clean up the SecurityContext.

what is spring security context holder

Conclusion

This is all about the Spring Security Authentication part. I will be coming up with two sequels of the same article regarding the Spring Security Authorization and the ExceptionHandling part. Till then, check out my other articles on Spring Framework.

LEAVE A REPLY

Please enter your comment!
Please enter your name here