Spring Security Architecture

SOLID

Spring Security follows a layered architecture that works cohesively to provide comprehensive security services for Java applications. The architecture consists of multiple layers, each serving a specific purpose. Here's an overview of how the Spring Security architecture layers work:

1. Authentication filters:

  • Authentication filters in Spring Security handle the authentication process for incoming requests.

  • It is the part of the Security Filter Chain, these filters focus on authentication-related tasks.

  • It processes user credentials (username and password) from incoming requests.

  • It extracts authentication tokens, allowing various authentication mechanisms (e.g., JSON Web Tokens).

  • It communicates with the Authentication Manager to perform user authentication.

  • It also collaborates with other filters in the Security Filter Chain to provide end-to-end security features.

2. Authentication Manager:

  • The Authentication Manager is responsible for authenticating users based on the provided credentials.

  • It contains one or more authentication providers, each supporting a specific type of authentication, such as in-memory, JDBC, LDAP, or custom providers.

  • Developers can configure the Authentication Manager to use multiple providers in a specified order.

3. Authentication Providers:

  • Authentication Providers perform the actual authentication of users.

  • Spring Security supports various authentication providers, including DaoAuthenticationProvider (Database-based), LdapAuthenticationProvider, and custom providers.

4. PasswordEncoder:

  • Encodes passwords during authentication and allows for secure storage of user credentials. Various implementations are available, such as BCryptPasswordEncoder and StandardPasswordEncoder.

  •                     
            @Bean
            public PasswordEncoder passwordEncoder() {
                return new BCryptPasswordEncoder();
            }
                        
                    
  • The BCryptPasswordEncoder is a widely used password encoder that uses a one-way hashing algorithm, making it more secure than storing plain-text passwords.

5. UserDetailsService:

  • The UserDetailsService interface is part of the authentication process and is responsible for loading user-specific data.

  • It is commonly implemented to retrieve user details from a database or any other data source during authentication.

  • Retrieves user details during the authentication process. It is responsible for loading user-specific data, such as username, password, and authorities, from a data source (e.g., database, LDAP).

6.1 InMemory User Details Service

  • InMemoryUserDetailsService is a concrete implementation of the UserDetailsService interface.

  • It allows developers to define user details directly in the application's code or configuration files.

  •                     
            @Bean
            public UserDetailsService userDetailsService() {
                UserDetails user = User.builder()
                    .username("user")
                    .password(passwordEncoder().encode("password"))
                    .roles("USER")
                    .build();
    
                UserDetails admin = User.builder()
                    .username("admin")
                    .password(passwordEncoder().encode("admin"))
                    .roles("ADMIN")
                    .build();
    
                return new InMemoryUserDetailsManager(user, admin);
            }
                        
                    

6.2 Custom User Details Service:

  • A custom user details service in Spring Security is an implementation of the UserDetailsService interface tailored to fetch user details from a custom data source.

  • Overrides the loadUserByUsername method to load user details based on the provided username.

  • Allows developers to define their logic for loading user details, enabling flexibility in integrating with various user management systems.

  •                     
            @Service
            public class CustomUserDetailsService implements UserDetailsService {
                @Override
                public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                    // Load user details from your data source
                }
            }
                        
                    

For more details, Please check out CustomUserDetailsService article in details

7. UserDetails

  • User details in Spring Security represent information about an authenticated user.

  • It is an interface which defining essential user details such as username, password, authorities, and account status

  • The User class is a common implementation of the UserDetails interface provided by Spring Security.

  • Specifies the roles and authorities granted to a user, determining their access permissions.

  • Represents the identity of an authenticated user during the application's runtime.

  • User details include information about the account's status, such as whether it is enabled, expired, or locked.