February 16th, 2023
Spring Security In-Memory Authentication using @Bean
This illustrates the use of Spring in-memory authentication.
We also look into how to customize the Spring Security AuthenticationManager to use Spring Security in-memory authentication and add multiple users with different attributes, authorities, and roles.
Let’s use Spring boot to quickly create and bootstrap spring applications. We configure Spring Security to use In-Memory Authentication in this spring boot application.
Tools and Technologies Used
- Spring Boot – 2.7.8
- Spring Framework – 5.7.6
- Spring Security – 5.7.6
- Maven – 3.8.7
- Spring Tool Suite IDE – 4.14.0.RELEASE
- OS – Linux 5.15.93-1-MANJARO
Development Steps
Let’s use below development steps to create this example:
- Creating a Spring Boot Application
- Project Structure
- Maven Dependencies – Pom.xml
- Spring Security In-Memory Authentication
- Running the Application
- Demo
- Conclusion
1. Creating a Spring Boot Application
There are many ways to create a Spring Boot application. You can refer below articles to create a Spring Boot application.
>> Create Spring Boot Project With Spring Initializer
>> Create Spring Boot Project in Spring Tool Suite [STS]
2. Project Structure
Following is the package or project structure for your reference
3. Maven Dependencies – Pom.xml
Make sure the following dependencies reside on the class-path.
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.7.8
com.example
in-memory
0.0.1-SNAPSHOT
in-memory
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.security
spring-security-test
test
org.springframework.boot
spring-boot-maven-plugin
4. Spring Security In-Memory Authentication
In the following configuration class, we are using the AuthenticationManagerBuilder with the In-memory UserDetailsManagerConfigurer to configure the Spring Security In-Memory Authentication.
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout()
.permitAll();
}
}
Notice that we are using a builder pattern to create multiple users with different attributes, authorities, and roles. This automatically configures a UserDetailsService which we can use.
Note that we have added a password storage format, for plain text, add {noop}. Prior to Spring Security 5.0, the default PasswordEncoder was NoOpPasswordEncoder which required plain text passwords. In Spring Security 5, the default is DelegatingPasswordEncoder, which required Password Storage Format like {noop}.
5. Simple Rest Web Service
Let’s create a simple rest service that is protected. We can obtain the current in-memory user by injecting the Authentication as an argument of the method.
In the following sample, we use Spring Boot CLI to encode a password value of
password
and get the encoded password of {bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW
:
package com.example.demo.controller;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WelcomeController {
@GetMapping("/")
public String greeting() {
return "Welcome: home";
}
@GetMapping("/login")
public String greeting(Authentication auth) {
UserDetails user = users().loadUserByUsername(auth.getName());
System.out.println(user);
return "Welcome: "+auth.toString();
}
@Bean
public UserDetailsService users() {
UserDetails user = User.builder()
.username("user")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
6. Running the Application
Let’s run the spring boot application with following entry point:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class InMemoryApplication {
public static void main(String[] args) {
SpringApplication.run(InMemoryApplication.class, args);
}
}
7. Demo
Hit this link in browser – http://localhost:8080. Below is the default login page provided by spring security. You can create your own custom login page here.
Leave a Reply