Как добавить пользователей в конструктор inMemoryAuthentication после его создания?

Мне удалось загрузить всех пользователей в AuthenticationManagerBuilder во время начальной загрузки приложения, но у меня есть требование добавить пользователей после запуска.

Startup:

public class WebSecurityConfig extends WebSecurityConfigurerAdapter

...

auth.inMemoryAuthentication().withUser(email).password(password).roles(roles.toArray(new String[roles.size()])).and().passwordEncoder(encoder());

Это отлично работает в определенный момент времени, но у меня есть прецедент, когда пользователи могут быть добавлены во время работы приложения.

По какому методу я могу выполнить этот пост-запуск (через контроллер/сервис)? Я думаю, что это может быть InMemoryUserDetailsManager (он содержит метод createUser()), но я не уверен, как ссылаться или настраивать его.

Ответы

Ответ 1

Следующий код будет делать то, что вы спрашиваете:

@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);
    }

}

Используя InMemoryUserDetailsManager, который вы настроили выше супер простого контроллера, который просто добавляет и проверяет наличие пользователя, будет выглядеть так:

@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";
    }
}

Также обратите внимание, что если вы используете Spring Boot autoconfiguration, вам нужно будет добавить

@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)

чтобы предотвратить Spring Загрузка с попытки автоконфигурации безопасности

Обновление Как отмечено @AdamMichalik, @EnableWebMvcSecurity устарел и должен быть заменен на @EnableWebSecurity

Ответ 2

Я изменил этот код:

inMemoryUserDetailsManager.createUser(new User(username, password, new ArrayList<GrantedAuthority>()));

из ответа @geoend на:

inMemoryUserDetailsManager.createUser(User.withUsername(username).password(password).roles("USER").build());

потому что по умолчанию у нового пользователя нет разрешений.