AccessDeniedException 上的 HTTP 401

HTTP 401 on AccessDeniedException

我有以下安全配置和 JwtFilter:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfig(
    val tokenService: TokenService,
) : WebSecurityConfigurerAdapter(), WebMvcConfigurer {

    override fun configure(http: HttpSecurity) {
        http
            .csrf().disable()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .addFilterAt(
                JwtFilter(authenticationManager(), tokenService),
                UsernamePasswordAuthenticationFilter::class.java
            )
    }
}

class JwtFilter(
    authManager: AuthenticationManager,
    private val tokenService: TokenService,
) : BasicAuthenticationFilter(authManager) {

    @Throws(IOException::class, ServletException::class)
    override fun doFilterInternal(
        req: HttpServletRequest,
        res: HttpServletResponse,
        chain: FilterChain
    ) {
        val header = req.getHeader("Authorization")
        if (header == null || !header.startsWith("Bearer")) {
            chain.doFilter(req, res)
            return
        }
        tokenService.extractUser(header)?.also {
            SecurityContextHolder.getContext().authentication = it
        }
        chain.doFilter(req, res)
    }
}

TokenService#extractUser 在 JWT 解析错误的情况下抛出 AccessDeniedException。我找不到将其映射到 HTTP 401 的方法。可以实现吗?

我尝试过使用 HttpSecurity#exceptionHandling() 以及在 @ControllerAdvice 中添加 @ExceptionHandler,但我总是收到 HTTP 403。

感谢 线程,我设法通过将以下两行添加到我的 WebSecurityConfigurerAdapter#configure:

来解决它
.exceptionHandling()
.authenticationEntryPoint(HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))