使用 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 以避免出现此警告?
然而,对于遇到这个问题的其他人来说,我是一名 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();
}
}