Spring Boot更新后@RestController抛异常均返回403问题排查
问题:Spring Boot升级后接口抛出异常时客户端收到403而非正确状态码
已解决(编辑补充)
- 解决方法:重新配置Spring Security。旧配置与新版Spring不兼容,参考官方新文档重新编写Security配置后问题解决,暂未明确具体是哪项配置导致的冲突。
问题详情
刚升级Spring Boot应用后,发现无论@RestController抛出什么异常,客户端都会收到403响应。示例代码如下:
@GetMapping @PreAuthorize("hasAnyRole('ADMIN')") fun getAllUserData(@RequestParam("start") start: Long = 0, @RequestParam("end") end: Long = 2684276745101): List<UserLog> { throw(NotFoundException()) // 移除该行后方法正常运行 return userLogMapper.findFirst(maxRows, start, end) } @ResponseStatus(code = HttpStatus.NOT_FOUND) class NotFoundException : RuntimeException()
使用已认证的ADMIN用户调用该接口时,客户端收到403,调试日志如下:
2023-05-24T20:21:23.285-04:00 DEBUG 134852 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND 2023-05-24T20:21:23.286-04:00 DEBUG 134852 --- [nio-8081-exec-2] o.s.security.web.FilterChainProxy : Securing GET /error?start=1672549200000&end=1684974082325 2023-05-24T20:21:23.287-04:00 DEBUG 134852 --- [nio-8081-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2023-05-24T20:21:23.287-04:00 DEBUG 134852 --- [nio-8081-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2023-05-24T20:21:23.288-04:00 DEBUG 134852 --- [nio-8081-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2023-05-24T20:21:23.288-04:00 DEBUG 134852 --- [nio-8081-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2023-05-24T20:21:23.288-04:00 DEBUG 134852 --- [nio-8081-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext 2023-05-24T20:21:23.289-04:00 DEBUG 134852 --- [nio-8081-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
如何让404、500等异常正常返回对应状态码?目前所有异常都会导致客户端收到403,怀疑是Spring Security升级到3.0.6引发的问题。
当前安全配置代码
package com.saisols.survey.config import com.saisols.survey.dao.ConfigMapper import com.saisols.survey.dao.UserLogMapper import com.saisols.survey.spring_beans.JWTAuthenticationFilter import com.saisols.survey.spring_beans.JWTAuthorizationFilter import com.saisols.survey.spring_beans.JWTService import com.saisols.survey.spring_beans.SurveyUserDetailsService import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.web.SecurityFilterChain @Configuration @EnableWebSecurity(debug = false) // @EnableMethodSecurity(prePostEnabled = true) Don't enable yet... // Found more than one annotation of type interface org.springframework.security.access.prepost.PreAuthorize attributed to public java.util.List // 注:升级到Spring Boot 3 + JDK17后遇到该注释中的异常,暂时禁用了@EnableMethodSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) class BasicWebSecurityConfigAdapter{ @Autowired lateinit var jwtService: JWTService @Autowired lateinit var suds: SurveyUserDetailsService @Autowired lateinit var encoder: PasswordEncoder @Autowired lateinit var userLogMapper: UserLogMapper @Autowired lateinit var configMapper: ConfigMapper var twoFaEnabled: Boolean = false @Bean fun authenticationManager( authConfig: AuthenticationConfiguration ): AuthenticationManager { return authConfig.authenticationManager } @Bean fun securityFilterChain(http: HttpSecurity, authenticationManager: AuthenticationManager): SecurityFilterChain { twoFaEnabled = configMapper.findByKey("survey.2fa_enabled")?.configValue!!.equals("true") http.authorizeHttpRequests() .requestMatchers("/").permitAll() .requestMatchers("/login-state").permitAll() .requestMatchers("/verify-code").permitAll() .requestMatchers("/oauth2/**").permitAll() .anyRequest().authenticated() .and() // .httpBasic() .addFilter(JWTAuthorizationFilter(authenticationManager, jwtService, suds, twoFaEnabled)) .addFilter(JWTAuthenticationFilter(authenticationManager, jwtService, userLogMapper)) .cors() .and() .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //http.cors().disable() return http.build() } /*override fun configure(auth: AuthenticationManagerBuilder) { auth.userDetailsService(suds).passwordEncoder(encoder) }*/ }
尝试的解决方案及结果
按照建议添加.requestMatchers( "/error").permitAll()后,日志显示仍返回403:
2023-05-24T20:58:21.678-04:00 DEBUG 140108 --- [io-8081-exec-10] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error?start=1672549200000&end=1684976301369", parameters={masked} 2023-05-24T20:58:21.678-04:00 DEBUG 140108 --- [io-8081-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2023-05-24T20:58:21.683-04:00 DEBUG 140108 --- [io-8081-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json] 2023-05-24T20:58:21.684-04:00 DEBUG 140108 --- [io-8081-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Wed May 24 20:58:21 EDT 2023, status=403, error=Forbidden, path=/user-log}] 2023-05-24T20:58:21.689-04:00 DEBUG 140108 --- [io-8081-exec-10] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 403
内容的提问来源于stack exchange,提问作者mikeb
相关产品推荐
相关产品推荐

