带Spring Security的Sping Boot 3拦截异常我不希望这样

ia2d9nvy  于 2023-01-30  发布在  Spring
关注(0)|答案(2)|浏览(149)

我正在使用Spring Boot 3.0.2和Spring Security构建一个API,我已经构建了安全过滤器链,它在阻止未经验证的请求方面工作得很好。如果我没有正确地提供内容类型头,我希望返回415状态码,它可以很好地返回,而不会受到SpringSecurity的影响。但是对于Spring Security,它似乎被拦截并返回403。
WebSecurityConfig

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
               .cors().and()
               .csrf().disable()
               .authorizeHttpRequests(auth -> auth
                   .requestMatchers("/auth**").permitAll()
                   .anyRequest().authenticated())
               .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
               .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
               .userDetailsService(jpaUserDetailsService)
               .build();
}

验证筛选器:

@Component
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
    private final JwtUtils jwtUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String jwtToken = request.getHeader(AUTHENTICATION_HEADER);

        if (jwtToken != null && jwtToken.startsWith("Bearer ")) {
            jwtToken = jwtToken.split(" ")[1];
            if (jwtUtils.isValidToken(jwtToken)) {
                UserDetails userDetails = new UserSecurity(jwtUtils.extractUser(jwtToken));
                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails,
                        null, userDetails.getAuthorities());
                auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
        }

        filterChain.doFilter(request, response);
    }
}

静止控制器:

@RestController
@RequestMapping(value = "auth", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public class AuthController {
    @GetMapping
    public Object test() {
        Map<String, String> test = new HashMap<>();
        test.put("key", "val");

        return test;
    }
}

有没有办法只返回403异常,如果它实际上是一个未经验证的错误?而不是对每一个异常?

tf7tbtn2

tf7tbtn21#

您必须允许URL /error才能看到错误。

tzxcd3kk

tzxcd3kk2#

您必须打开错误端点,请参阅Sping Boot 2.0迁移指南:

默认安全性

安全自动配置不再公开选项,而是尽可能使用Spring Security默认值,一个值得注意的副作用是使用Spring Security的内容协商进行授权(表单登录)。
Sping Boot 2.0没有太多地偏离Spring Security的默认设置,因此在Spring Boot 1.5中绕过Spring Security的一些端点现在默认是安全的。这些端点包括错误端点和静态资源的路径,如/css/**/js/**/images/**/webjars/**/**/favicon.ico。如果您想打开这些端点,你需要明确地配置它。
您修改的安全链配置:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
               .cors().and()
               .csrf().disable()
               .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/error").permitAll()
                    .requestMatchers("/auth**").permitAll()
                    .anyRequest().authenticated())
               .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
               .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
               .userDetailsService(jpaUserDetailsService)
               .build();
}

相关问题