当我们登录系统并访问未映射(不存在)的资源时,我们会收到 404 错误,但它不会发生在我身上,我收到 401 错误,但它不会产生任何错误有道理,因为我已经登录了,并且我认为这是一个 Spring 安全错误。
过滤器:
if (tokenJWT != null) {
User user = recoverUser(tokenJWT);
Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication); // The authentication is being done here, the user is already logged!
}
filterChain.doFilter(request, response); // Here, the request goes to the next class, SecurityConfigurations.
}
安全配置:
@RequiredArgsConstructor
@EnableWebSecurity
@Configuration
@Primary
public class SecurityConfigurationsImpl {
private final TokenService tokenService;
private final UserRepository userRepository;
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager
authenticationManager(AuthenticationConfiguration
authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws
Exception {
http.authorizeHttpRequests()
.requestMatchers("/v3/api-docs/**", "/swagger-ui.html",
"/swagger-ui/**").permitAll()
.requestMatchers(AntPathRequestMatcher.antMatcher("/h2-
console/**")).permitAll()
.requestMatchers("/auth", "/users/register").permitAll()
.requestMatchers("/users", "/users/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and().cors()
.and().headers().frameOptions().disable()
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy
(SessionCreationPolicy.STATELESS)
.sessionCreationPolicy
.and().addFilterBefore(new
AuthenticationJWTFilter(tokenService, userRepository),
UsernamePasswordAuthenticationFilter.class()
.exceptionHandling().authenticationEntryPoint(new
UnauthorizedHandler())
.and().exceptionHandling().accessDeniedHandler(new
ForbiddenHandler());
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new
CorsConfiguration().applyPermitDefaultValues();
configuration.setAllowedMethods(Arrays.asList("POST", "GET",
"PUT", "DELETE", "OPTIONS"));
final UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
当我登录并访问任何不存在的资源时,我确实收到了 404 错误,但我收到了 401。enter image description here
我确定 token 是有效的,当我尝试访问不存在的资源时,问题就会发生! 当我将 Spring Boot 版本更新到 3.0.1 时,它开始发生
我尝试在 YouTube 上观看视频,在 Google 上查找错误解决方案...
最佳答案
默认情况下,Spring 会处理所有传入请求,即使您自己没有为其定义特定的 @Controller
也是如此。它尝试将此类未映射的请求作为静态资源请求来处理,因为默认的静态路径模式包括所有内容:/**
。如果失败,它将尝试呈现错误网页(默认为 /error
),该网页属于您的 anyRequest().authenticated()
配置并导致401
响应。要查看错误页面,请将 /error
添加到您的 permitAll()
配置中。
或者,如果您不想使用默认错误页面并自行处理错误,则需要执行以下操作:
- 定义异常处理程序,例如:
@ControllerAdvice public class MyAdvice { @ExceptionHandler(NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public MyResponse handleUnknownResource(NoHandlerFoundException e) { // handle it } }
- 覆盖静态路径模式,使其不处理所有内容。例如,要仅包含
/static
文件夹,请配置spring.mvc.static-path-pattern:/static
。 - 现在它不会为您的请求找到处理程序,但默认情况下它仍会将您重定向到
/error
,而不是抛出您可以自行处理的异常。要覆盖该行为,请配置spring.mvc.throw-exception-if-no-handler-found: true
关于java - Spring Security 6 返回错误 401 而不是 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75240011/