简体   繁体   English

Spring Boot 3 with Spring Security Intercepts exceptions 我不希望它

[英]Spring Boot 3 with Spring Security Intercepts exceptions I don't want it to

I'm building an API using Spring Boot 3.0.2 with Spring Security, I've built out the security filter chain and it's working fine as far as blocking unauthenticated requests.我正在使用 Spring Boot 3.0.2 和 Spring Security 构建一个 API,我已经构建了安全过滤器链,它在阻止未经身份验证的请求方面运行良好。 But I have a RestController class that accepts application/json , and if I don't supply the content type header correctly I want the 415 status code returned.但是我有一个接受application/jsonRestController class,如果我没有正确提供内容类型 header,我希望返回 415 状态代码。 Which gets returned fine without Spring Security in the way.在没有 Spring 安全的情况下,它可以正常返回。 But with Spring Security it seems it's being intercepted and returning a 403 instead.但是对于 Spring Security,它似乎被拦截并返回了 403。

WebSecurityConfig : 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();
}

Auth Filter:授权过滤器:

@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);
    }
}

Rest Controller: Rest Controller:

@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;
    }
}

Is there a way to only return the 403 exception if it actually is an unauthenticated error?如果它实际上是一个未经身份验证的错误,有没有办法只返回 403 异常? Not for every single exception?不是针对每一个例外?

You have to permit the URL /error to see the error.您必须允许 URL /error 才能看到错误。

You have to open the error endpoint, see Spring Boot 2.0 Migration Guide :您必须打开错误端点,请参阅Spring Boot 2.0 迁移指南

Default Security默认安全

The security auto-configuration no longer exposes options and uses Spring Security defaults as much as possible.安全自动配置不再公开选项并尽可能使用 Spring 安全默认值。 One noticeable side effect of that is the use of Spring Security's content negotiation for authorization (form login).一个明显的副作用是使用 Spring Security 的内容协商进行授权(表单登录)。

Spring Boot 2.0 doesn't deviate too much from Spring Security's defaults, as a result of which some of the endpoints that bypassed Spring Security in Spring Boot 1.5 are now secure by default. Spring Boot 2.0 与 Spring Security 的默认设置没有太大偏差,因此一些在 Spring Boot 1.5 中绕过 Spring Security 的端点现在默认是安全的。 These include the error endpoint and paths to static resources such as /css/** , /js/** , /images/** , /webjars/** , /**/favicon.ico .其中包括错误端点和 static 资源的路径,例如/css/**/js/**/images/**/webjars/**/**/favicon.ico If you want to open these up, you need to explicitly configure that.如果你想打开它们,你需要明确地配置它。

Your modified security chain configuration:您修改后的安全链配置:

@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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM