Spring 安全警告:如何修复 AuthenticationProvider 与 UserDetailsService 配置?

问题描述 投票:0回答:1

使用 Spring Security 配置启动 Spring Boot 应用程序时遇到警告。警告消息是:

WARN [  restartedMain] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with an AuthenticationProvider bean. UserDetailsService beans will not be used for username/password login. Consider removing the AuthenticationProvider bean. Alternatively, consider using the UserDetailsService in a manually instantiated DaoAuthenticationProvider.

我已经在 Spring Boot 应用程序中配置了基于 JWT 的身份验证。以下是我的配置的相关部分:

安全过滤链:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize ->
                        authorize
                                .requestMatchers("/assets/**", "/css/**", "/images/**", "/js/**").permitAll()
                                .requestMatchers("/", "/about", "/contact").permitAll()
                                .requestMatchers("/auth/**").permitAll()
                                .anyRequest().authenticated()
                )
                .sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
                .authenticationProvider(authenticationProvider)
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

ApplicationBeanConfiguration相关部分:

@Configuration
public class ApplicationBeanConfiguration {

    private final UserRepository userRepository;

    public ApplicationBeanConfiguration(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }

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

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());

        return authProvider;
    }
}

无论我包含还是排除 AuthenticationProvider bean,警告都会持续存在。应用程序启动时出现警告,表明 AuthenticationProvider 配置可能与 UserDetailsService 冲突。

该警告表明我的设置可能配置不正确。具体来说,它表明 AuthenticationProvider bean 正在覆盖 UserDetailsService,这可能会导致用户名/密码身份验证出现问题。

我应该如何正确配置 Spring Security 以避免出现此警告?

java spring-boot authentication spring-security configuration
1个回答
0
投票

然而,对于遇到这个问题的其他人来说,我是一名 Spring Security 新手(因为我遵循了类似的教程)。关键问题是,如果您使用自动配置概念,则无需创建身份验证提供程序或管理器。 (@Jzheaux 的评论是正确的)。

在教程中这样做的主要原因似乎是使用PasswordEncoder 和UserDetailService 注册AuthProvider,但是如果您将它们定义为bean/服务,Spring 将会选择它们。如果您正在使用 JWT,则主要工作是在 JWT 过滤器中,尽管 Toerktumlare 的评论很激进。下面是我的工作配置类,我用它来管理 JWT 的安全性。

@配置 公共类安全配置{

@Value("${spring.security.enabled}")
private boolean securityEnabled;

private final JwtRequestFilter jwtRequestFilter;

@Autowired
public SecurityConfiguration(JwtRequestFilter jwtRequestFilter) {
    this.jwtRequestFilter = jwtRequestFilter;
}

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

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
    return configuration.getAuthenticationManager();
}


@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    if (securityEnabled) {
        http
                .cors(cors -> cors.disable())
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/auth", "/error", "/auth/**").permitAll()
                        .anyRequest().authenticated()
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling(exception -> exception
                        .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
                );
    } else {
        http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll())
                .csrf(csrf -> csrf.disable());
    }
    return http.build();
}

}

© www.soinside.com 2019 - 2024. All rights reserved.