The preceding article in this series concluded with a simplified architecture/workflow of Spring security as it pertains to in-memory Authentication.
In-memory Authentication in Spring Security serves as a middle ground between the default configuration, which allows only a single user profile, and the more comprehensive Database Authentication.
Table of Contents
Pre-requisites
Introducing key players in-memory authentication
Step by step implementation of in-memory authentication
Understanding the interaction between key players
Pre-requisites
For a better understanding of this article, I recommend going through the previous article in the series.
Familiarity with Java and Spring Boot is advised, along with a fundamental understanding of security principles encompassing authentication, authorization, and encryption.
The first article offers a comprehensive introduction to the architecture of Spring Security.
In the second part, we delve deeper into the default security configuration offered by Spring Security 6,
With in-memory Authentication, user credentials are stored directly in the application's memory during runtime. This approach is suitable for small-scale applications or for testing and development purposes. It allows you to define user profiles, including usernames, passwords, and roles, directly in the application's configuration.
Application configuration? The SecurityConfig class serves as a central hub for configuring the security of your application. It provides a single location to gather and organize all the security-related settings, simplifying the management and comprehension of your application's security aspects.
Step 1: Create a SecurityConfig class. Of course, you can call it somethng different.
It is annotated with @Configuration and @EnableWebSecurity. The latter is used to enable web security features in a Spring Boot application, also it indicates that the class will provide the necessary configuration for securing your web application.
A quick recap will remind us of the roles of the key players.
Step 2: Create the SecurityFilterChain.
It is annotated with @Bean. In very simple terms, you are letting Spring take note of the object of the SecurityFilterChain method. This means Spring becomes responsible for creating and managing the object, for instance, in dependency injection.
The method takes the HttpSecurity object and throws an exception.
The
csrf.disable()
prevents cross-site request forgeryIt can be said that every request made by the client at the controller can either be ‘permitted’ i.e. requiring no authentication or ‘authenticated’ i.e. requiring authentication. This corresponds to the use of
permitAll()
andanyRequest().authenticated()
.HTTP Basic authentication is a commonly used authentication method. When you include
httpBasic(Customizer.withDefaults())
in your security configuration, your application expects clients to provide their username and password in the HTTP headers of each request. The server verifies these credentials and allows access to protected resources if they are valid.
Step 3: Create beans of PasswordEncoder, AuthenticationManager
Observe that each method is annotated with @Bean
The passwordEncoder returns a BCryptPasswordEncoder. It is a password encoder in Spring Security that securely hashes passwords using the bcrypt algorithm.
The Authentication Manager in Spring Security simplifies authentication by using the
.authenticate()
method internally.It collaborates with the AuthenticationProvider and UserDetailsService, which work behind the scenes.
The AuthenticationProvider verifies user credentials, while the UserDetailsService loads user details from a data source. These components work together to authenticate users.
The Authentication Manager in Spring Security simplifies authentication, allowing developers to focus on security rules and configuration, without worrying about the intricate details. 🥂
Step 4: Create the UserDetailsService
In in-memory authentication, the UserDetailsService does two things.
It allows us to create instances of users within our application. Note that the users are of the type,
UserDetails
which is provided by spring security. The created users are then saved in an instance ofInMemoryUserDetailsManager
.It allows us to retrieve users from our in-built database.
Notice the role of the p
asswordEncoder
in encoding our raw password to an encrypted form. It is this encrypted form that is stored in our database.
"Simplicity is the ultimate sophistication." - Leonardo da Vinci
Understanding InMemory Authentication in one paragraph
Remember, the client makes a request to our controller. The SecurityFilterchain determines whether this request is permitted or requires authentication to be permitted. Should it require authentication which simply means the user is first identified before being allowed to make the request, the security filter calls on the Authentication Manager to help identify this user. The information provided in the request made i.e. username and password is compared with that in our in-memory database with the help of userDetailsService
.
As you will see, virtually all the configuration is done within the SecurityConfig class. This is an apparent advantage of in-memory Authentication. It is however quite strenuous to implement with a large number of users. Imagine creating a thousand users within the UserDetailsService
Method. This calls for database Authentication.
In the next installment of this series, we will go about implementing database authentication. We find that we do not have to make too many changes. However, those little changes will require the creation of new entities and classes.
Before attempting this, we will review the concept of authorization. While Authentication deals with identifying a user and permitting him in, authorization looks at the level of access the already identified user possesses. To illustrate this with a simpler analogy, consider a house. Authentication would be like allowing a guest into your living room and confirming their identity. However, authorization determines the specific areas of the house they can access. For example, as the owner of the house, you have authorization to enter the master bedroom, while the guest may not have that level of access.
To be continued…