Próbuję użyć źródła bezpieczeństwa Uwierzytelnianie JDBC w aplikacji internetowej Spring Boot. Oto konfiguracja (wiele uproszczona, istotna):

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

Oto kontroler:

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

Kiedy zaczynam aplikację, widzę, że:

  • AuthenticicationManagerbuilder dostaje skonfigurowany JDBCudm:

enter image description here

Ale brakuje jakiegoś kroku?

  • InmemoryUserDetailsManager jest instancji z domyślnym użytkownikiem Security Spring Security:

enter image description here

  • Kontroler, po utworzeniu instancji, odbiera INMEMORYUSERDETEAXManager:

enter image description here

Oznacza to, że kiedy próbuję stworzyć nowy użytkownik, używa inmemoryudm zamiast jdbcudm, którego chciałbym użyć. Dlaczego?

Rozwiązanie robocze.

Skonfigurujemy już UserTetailsService przez JDBcuserdetailsmanagerConfigrer, ale nie wystawił go jako fasoli.

    @Autowired
    @Bean
    public UserDetailsManager configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        JdbcUserDetailsManagerConfigurer jdbcUserDetailsManagerConfigurer = auth.jdbcAuthentication()
                .dataSource(dataSource)
                .withDefaultSchema();
        return jdbcUserDetailsManagerConfigurer.getUserDetailsService();
    }
0
Monopole Magnet 24 marzec 2020, 10:22

2 odpowiedzi

Najlepsza odpowiedź

W konfiguracji zastępują userDetailsServiceBean() i pozwól, aby zadzwonić do super metodę i dodać adnotację @Bean, aby skonfigurowana usługa była dostępna. Jest to również wyjaśnione Oto w 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();
    } 
}

Ponadto, ponieważ chcesz użyć konfiguracji zamiast obiektu sprężyny, może być konieczne dodanie @EnableWebSecurity, aby wyłączyć domyślne domyślne sprężyny.

2
M. Deinum 26 marzec 2020, 06:54

Utwórz SecurityConfiguration rozciągnij się z WebSecurityConfigureRadapter , dodaj @enableWebSecurity i odsłonić jdbcuserdetailsManager jako @Bean.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration
   extends WebSecurityConfigurerAdapter {

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

/// etc.
}
1
Marco Behler 26 marzec 2020, 12:30