Spring Security 6.0 Dao 身份验证

Jsc*_*ery 5 java authentication spring spring-security spring-boot

我正在尝试创建一个项目来了解有关 Spring Security 的更多信息,并且尝试遵循从安全过滤器链 -> 身份验证管理器 -> 身份验证提供程序 -> UserDetailsS​​ervice -> DB开始的流程

我一直参考的流程: 流程图

我的安全配置:

@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig{
    DetailService userDetailService;

    @Bean
    public PasswordEncoder getPassWordEncoder() {
        return new BCryptPasswordEncoder(15);
    }

    @Bean
    DaoAuthenticationProvider authProvider(){
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailService);
        authProvider.setPasswordEncoder(getPassWordEncoder());
        return authProvider;
    }

    @Bean
    public ProviderManager authManagerBean(HttpSecurity security) throws Exception {
        return (ProviderManager) security.getSharedObject(AuthenticationManagerBuilder.class)
                .authenticationProvider(authProvider()).
                build();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/login/**", "/css/**", "/js/**", "/registration/**").permitAll()
                .anyRequest().authenticated())
                .csrf().disable()
                .formLogin(form -> form.loginPage("/login")
                .defaultSuccessUrl("/home")
                .failureForwardUrl("/login-failure?error=true"))
                .logout().permitAll();
        return http.build();
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

@RequestMapping("/login.html")
public String login(@RequestBody UserDTO dto) {

    Authentication authentication = authenticationManager.
            authenticate(new UsernamePasswordAuthenticationToken(dto.getUsername(), dto.getPassword()));

    return "/login.html";
}
Run Code Online (Sandbox Code Playgroud)

根据我的阅读,身份验证/提供程序管理器接收一个身份验证对象,该对象是根据控制器处理的登录表单中的用户名密码凭据创建的。

这就是我在控制器中实现的。

问题:

  • 如何继续将从控制器创建的身份验证对象传递给提供程序管理器?(我知道这可能是错误的,但是)我是否向 AuthenticationManager @bean 添加另一个参数
  • 我也有点不稳定,ProviderManager这是否正确?

非常感谢大家的阅读:)

Mar*_*gio 8

我对 ProviderManager 也有点不稳定,这是否正确?

您可以自己创建一个,而不是依赖 Spring Security 内部来创建AuthenticationManager(难以理解和调试),因为您没有使用 Spring Security 提供的任何开箱即用的身份验证机制。

您可以将您的ProviderManagerbean 更改为:

@Bean
public ProviderManager authManagerBean(AuthenticationProvider provider) {
    return new ProviderManager(provider);
}
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,因为您不会AuthenticationProvider单独使用该 bean,所以不要将其公开为 bean,而是执行以下操作:

@Bean
public AuthenticationManager authenticationManager(){
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailService);
    authProvider.setPasswordEncoder(getPassWordEncoder());
    return new ProviderManager(authProvider);
}
Run Code Online (Sandbox Code Playgroud)

如何继续将从控制器创建的身份验证对象传递给提供程序管理器?(我知道这可能是错误的,但是)我是否向 AuthenticationManager @bean 添加另一个参数?

我想我没有听懂你的要求。当您调用 时,对象Authentication(在您的情况下 a )UsernamePasswordAuthenticationToken被传递给。ProviderManagerauthenticationManager.authenticate(...)