web-dev-qa-db-fra.com

Comment puis-je ajouter des utilisateurs au générateur inMemoryAuthentication après sa construction?

J'ai réussi à charger tous les utilisateurs dans AuthenticationManagerBuilder lors du chargement initial de l'application, mais j'ai l'obligation d'ajouter des utilisateurs après le démarrage.

Commencez:

public class WebSecurityConfig extends WebSecurityConfigurerAdapter

...

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

Cela fonctionne très bien pour un moment donné, mais j'ai un cas d'utilisation où des utilisateurs peuvent être ajoutés pendant l'exécution de l'application.

Par quelle méthode puis-je faire ce post-démarrage (via contrôleur/service)? Je pense que cela pourrait être la InMemoryUserDetailsManager (elle contient la méthode createUser()) mais je ne sais pas comment la référencer ou la configurer.

22
ehiggins

Le code suivant fera ce que vous demandez:

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

}

En utilisant la variable InMemoryUserDetailsManager que vous avez configurée ci-dessus, un contrôleur super simple qui ajoute et vérifie l'existence d'un utilisateur ressemblerait à ceci:

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

Notez également que si vous utilisez la configuration automatique de Spring Boot, vous devrez ajouter 

@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)

empêcher Spring Boot d'essayer de configurer automatiquement la sécurité

Mise à jour Comme l'a noté @AdamMichalik, @EnableWebMvcSecurity est obsolète et doit être remplacé par @EnableWebSecurity

29
geoand

J'ai changé ce code:

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

de @ geoend´s answer à:

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

car par défaut, un nouvel utilisateur ne dispose d'aucune autorisation.

1
Dmitry Golikov