I have managed to load all the users into the AuthenticationManagerBuilder during the initial load of the application, but I have a requirement to add users post-startup.
Startup:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter ... auth.inMemoryAuthentication().withUser(email).password(password).roles(roles.toArray(new String[roles.size()])).and().passwordEncoder(encoder());
This works great for a point in time, but I have a use case where users can be added while the application is running.
By which method can I do this post-startup (via controller/service)? I'm thinking it might be the InMemoryUserDetailsManager
(it contains the createUser()
method) but I'm not sure how to reference or configure it.
inMemoryAuthentication() is the method of AuthenticationManagerBuilder class is used to perform in-memory authentication in the Spring Security. This method is used for creating the user with respective roles and passwords. Let's discuss how to implement inmemoryAuthentication in Spring Security.
AuthenticationManagerBuilder. parentAuthenticationManager(AuthenticationManager authenticationManager) Allows providing a parent AuthenticationManager that will be tried if this AuthenticationManager was unable to attempt to authenticate the provided Authentication .
The following code will do what you are asking:
@Configuration @EnableWebMvcSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //whatever here } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(inMemoryUserDetailsManager()); } @Bean public InMemoryUserDetailsManager inMemoryUserDetailsManager() { final Properties users = new Properties(); users.put("user","pass,ROLE_USER,enabled"); //add whatever other user you need return new InMemoryUserDetailsManager(users); } }
Using the InMemoryUserDetailsManager
you configured above a super simple controller that just adds and checks for the existence of a user would look like:
@RestController @RequestMapping("user") public class SimpleSecurityController { private final InMemoryUserDetailsManager inMemoryUserDetailsManager; @Autowired public SimpleSecurityController(InMemoryUserDetailsManager inMemoryUserDetailsManager) { this.inMemoryUserDetailsManager = inMemoryUserDetailsManager; } @RequestMapping("exists/{username}") public boolean userExists(@PathVariable("username") String username ) { return inMemoryUserDetailsManager.userExists(username); } @RequestMapping("add/{username}/{password}") public String add(@PathVariable("username") String username, @PathVariable("password") String password) { inMemoryUserDetailsManager.createUser(new User(username, password, new ArrayList<GrantedAuthority>())); return "added"; } }
Also note that if you are using Spring Boot's autoconfiguration you will need to add
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
to prevent Spring Boot from trying to autoconfigure security
Update As noted by @AdamMichalik, @EnableWebMvcSecurity
is deprecated and should be replaced by @EnableWebSecurity
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With