在Dispatcher Servlet Spring Security中处理请求之前出现错误403(Forbidden)

a64a0gku  于 2024-01-05  发布在  Spring
关注(0)|答案(1)|浏览(177)

此问题在此处已有答案

Spring Boot 3 with Spring Security Intercepts exceptions I don't want it to(2个答案)
23天前关闭
我在使用Spring Security的应用程序中遇到了问题。如果出现任何错误,在请求到达Dispatcher Servlet之前,返回错误状态403(禁止)。
问题甚至在请求到达Dispatcher Servlet之前就发生了。例如,当我尝试访问/API/v1/offer路径时,我验证字段,发生错误,之后Spring security发送403响应。即使我写了一个不存在的URL而不是404响应(未找到),我也会得到403响应。
如果您能在通过Dispatcher Servlet传递请求之前就如何解决此问题提供任何建议或提示,我将不胜感激。
下面是我的Spring Security配置:

  1. @Configuration
  2. @EnableWebSecurity
  3. @RequiredArgsConstructor
  4. @EnableMethodSecurity
  5. public class SecurityConfiguration {
  6. private final AuthenticationProvider authenticationProvider;
  7. private final LogoutHandler logoutHandler;
  8. @Value("${adapter.controller.base-path}")
  9. private String basePath;
  10. @Bean
  11. public SecurityFilterChain securityFilterChain(HttpSecurity http, UserDetailsService userDetailsService, JwtService jwtService) throws Exception {
  12. http
  13. .csrf()
  14. .disable()
  15. .cors()
  16. .and()
  17. .authorizeHttpRequests(
  18. c -> c
  19. .requestMatchers("/api/v1/employee/**").hasAnyRole(ADMIN.name(), USER.name(), HR.name())
  20. .requestMatchers(GET, basePath + "/employee/**").hasAnyAuthority(ADMIN_READ.name(), USER_READ.name())
  21. .requestMatchers(POST, basePath + "/employee/**").hasAnyAuthority(ADMIN_CREATE.name(), USER_CREATE.name())
  22. .requestMatchers(PUT, basePath + "/employee/**").hasAnyAuthority(ADMIN_UPDATE.name(), USER_UPDATE.name())
  23. .requestMatchers(DELETE, basePath + "/employee/**").hasAnyAuthority(ADMIN_DELETE.name(), USER_DELETE.name())
  24. .anyRequest()
  25. .authenticated())
  26. .sessionManagement()
  27. .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  28. .and()
  29. .authenticationProvider(authenticationProvider)
  30. .addFilterBefore(new JwtAuthenticationFilter(userDetailsService, jwtService), UsernamePasswordAuthenticationFilter.class)
  31. .logout()
  32. .logoutUrl(basePath + "/auth/logout")
  33. .addLogoutHandler(logoutHandler)
  34. .logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
  35. return http.build();
  36. }
  37. @Bean
  38. public WebSecurityCustomizer ignoringCustomizer() {
  39. return (web) -> web.ignoring().requestMatchers(basePath + "/auth", "/swagger-ui/**", "/v3/api-docs/**");
  40. }
  41. }

字符串
下面是我的自定义过滤器:

  1. @Slf4j
  2. @RequiredArgsConstructor
  3. public class JwtAuthenticationFilter extends OncePerRequestFilter {
  4. public static final String BEARER_SUBSTRING = "Bearer ";
  5. private final UserDetailsService userDetailsService;
  6. private final JwtService jwtService;
  7. private final AuthenticationEntryPoint entryPoint = new BearerTokenAuthenticationEntryPoint();
  8. @Override
  9. protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException {
  10. final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
  11. final String jwt;
  12. final String userEmail;
  13. if (authHeader == null || !authHeader.startsWith(BEARER_SUBSTRING)) {
  14. log.error("Authentication headers not found.");
  15. entryPoint.commence(request, response, new AuthenticationCredentialsNotFoundException("Authentication headers not found."));
  16. return;
  17. }
  18. jwt = authHeader.substring(BEARER_SUBSTRING.length());
  19. try {
  20. userEmail = jwtService.extractEmail(jwt);
  21. if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
  22. UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
  23. if (jwtService.isTokenValid(jwt, userDetails)) {
  24. UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
  25. authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
  26. SecurityContextHolder.getContext().setAuthentication(authToken);
  27. }
  28. }
  29. filterChain.doFilter(request, response);
  30. } catch (ExpiredJwtException e) {
  31. log.error(e.getMessage());
  32. entryPoint.commence(request, response, new CredentialsExpiredException(e.getMessage()));
  33. }
  34. }
  35. }

7fhtutme

7fhtutme1#

允许任何人访问错误端点:

  1. @Bean
  2. public SecurityFilterChain securityFilterChain(HttpSecurity http, UserDetailsService userDetailsService, JwtService jwtService) throws Exception {
  3. http
  4. .csrf()
  5. .disable()
  6. .cors()
  7. .and()
  8. .authorizeHttpRequests(
  9. c -> c
  10. .requestMatchers("error").permitAll()
  11. .requestMatchers("/api/v1/employee/**").hasAnyRole(ADMIN.name(), USER.name(), HR.name())
  12. .requestMatchers(GET, basePath + "/employee/**").hasAnyAuthority(ADMIN_READ.name(), USER_READ.name())
  13. .requestMatchers(POST, basePath + "/employee/**").hasAnyAuthority(ADMIN_CREATE.name(), USER_CREATE.name())
  14. .requestMatchers(PUT, basePath + "/employee/**").hasAnyAuthority(ADMIN_UPDATE.name(), USER_UPDATE.name())
  15. .requestMatchers(DELETE, basePath + "/employee/**").hasAnyAuthority(ADMIN_DELETE.name(), USER_DELETE.name())
  16. .anyRequest()
  17. .authenticated())
  18. .sessionManagement()
  19. .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  20. .and()
  21. .authenticationProvider(authenticationProvider)
  22. .addFilterBefore(new JwtAuthenticationFilter(userDetailsService, jwtService), UsernamePasswordAuthenticationFilter.class)
  23. .logout()
  24. .logoutUrl(basePath + "/auth/logout")
  25. .addLogoutHandler(logoutHandler)
  26. .logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
  27. return http.build();
  28. }

字符串
问题是,当错误发生时,Spring会将用户发送到/error端点,但在您的情况下,该端点是受保护的,因此当用户试图访问它时,它会被拒绝,用户会得到403。

展开查看全部

相关问题