I'm experimenting with spring-security for authentication and want to be able to add users at runtime. I figured using UserDetailsManager would be minimally intrusive. How do I make it available as a bean, so that I can access it in controllers and other objects?
The Code I was starting with is as follows:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource, PasswordEncoder enc) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).withDefaultSchema().passwordEncoder(enc)
.withUser("user").password(enc.encode("password")).roles("USER").and()
.withUser("admin").password(enc.encode("password")).roles("USER", "ADMIN");
}
jdbcAuthentication()
creates a JdbcUserDetailsManager
, everything works fine. But I don't know to how to access that after the web app's initialization. I tried two variants that didn't work:
@Bean
public UserDetailsManager userDetailsManager(DataSource dataSource,PasswordEncoder enc) throws Exception {
return new JdbcUserDetailsManagerConfigurer<>().dataSource(dataSource).withDefaultSchema().passwordEncoder(enc)
.withUser("user").password(enc.encode("password")).roles("USER").and()
.withUser("admin").password(enc.encode("password")).roles("USER", "ADMIN").and()
.getUserDetailsService();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsManager userDetailsManager) throws Exception {
auth.userDetailsService(userDetailsManager);
}
When filling out the login form, I get the following:
Table "USERS" not found; SQL statement:
select username,password,enabled from users where username = ? [42102-185]
So it seems that this does not initialize the bean properly. Second try:
@Bean
public UserDetailsManager userDetailsManager(AuthenticationManagerBuilder auth, DataSource dataSource, PasswordEncoder enc) throws Exception {
return auth.jdbcAuthentication().dataSource(dataSource).withDefaultSchema().passwordEncoder(enc)
.withUser("user").password(enc.encode("password")).roles("USER").and()
.withUser("admin").password(enc.encode("password")).roles("USER", "ADMIN").and()
.getUserDetailsService();
}
During initialization, I get:
java.lang.IllegalStateException: Cannot apply ...JdbcUserDetailsManagerConfigurer@3bd97b0d to already built object
So using the builder in an @Bean
method does not work either.