Почему InMemoryUserDetailsManager внедряется в этот контроллер, хотя я настроил JdbcUserDetailsManager в другом месте? - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь использовать Spring Security JDB C Аутентификация в веб-приложении Spring Boot. Вот (очень упрощенная, соответствующая) конфигурация:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer;

import javax.sql.DataSource;

@Configuration
public class SecurityConfiguration {
    @Autowired
    private DataSource dataSource;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        JdbcUserDetailsManagerConfigurer jdbcUserDetailsManagerConfigurer = auth.jdbcAuthentication()
                .dataSource(dataSource)
                .withDefaultSchema();
    }
}

Вот контроллер:

import org.adventure.inbound.UserFormData;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserDetailsManager userDetailsManager;

    public UserController(UserDetailsManager userDetailsManager) {
        this.userDetailsManager = userDetailsManager;
    }

    @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity<Void> registerUser(UserFormData userFormData) {
        userDetailsManager.createUser(
                User
                        .withUsername(userFormData.getUsername())
                        .password(userFormData.getPassword())
                        .authorities(new SimpleGrantedAuthority("ROLE_USER"))
                        .build());
        return ResponseEntity.created(null).build();
    }
}

Когда я запускаю приложение, я вижу, что:

  • AuthenticationManagerBuilder получает настроенный JDBCUDM:

enter image description here

но, возможно, отсутствует какой-либо шаг?

  • InMemoryUserDetailsManager создается с пользователем по умолчанию Spring Security:

enter image description here

  • Контроллер, когда создается экземпляр, получает InMemoryUserDetailsManager:

enter image description here

Это означает, что когда я пытаюсь создать нового пользователя, он использует InMemoryUDM вместо JDBCUDM, который я хотел бы использовать. Почему это так?

Рабочее решение

Мы уже настроили UserDetailsService через JdbcUserDetailsManagerConfigurer, но не представили его как компонент.

    @Autowired
    @Bean
    public UserDetailsManager configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        JdbcUserDetailsManagerConfigurer jdbcUserDetailsManagerConfigurer = auth.jdbcAuthentication()
                .dataSource(dataSource)
                .withDefaultSchema();
        return jdbcUserDetailsManagerConfigurer.getUserDetailsService();
    }

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

В вашей конфигурации переопределите userDetailsServiceBean(), и позвольте ему вызывать метод super и добавьте аннотацию @Bean, чтобы сделать настроенную службу доступной. Это также объясняется здесь в Javadocs.

@Configuration
public class SecurityConfiguration extends WebSecutiryConfigurerAdapter {
    @Autowired
    private DataSource dataSource;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        JdbcUserDetailsManagerConfigurer jdbcUserDetailsManagerConfigurer = auth.jdbcAuthentication()
                .dataSource(dataSource)
                .withDefaultSchema();
    }

    @Bean
    public UserDetailsService userDetailsServiceBean()
                                          throws java.lang.Exception {
        return super.userDetailsServiceBean();
    } 
}

Кроме того, поскольку вы хотите использовать свою конфигурацию вместо Spring Boot, вам может потребоваться добавить @EnableWebSecurity, чтобы отключить настройки Spring Boot по умолчанию.

1 голос
/ 24 марта 2020

Сделайте вашу конфигурацию безопасности расширенной из WebSecurityConfigurerAdapter , добавьте @ EnableWebSecurity и , чтобы представить JdbcUserDetailsManager как @ Bean.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration
   extends WebSecurityConfigurerAdapter {

    @Bean
    public JdbcUserDetailsManager userDetailsManager() {
        return yourJdbcUserDetailsManager;
    }

/// etc.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...