Issue
I have the following security config and 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
throws an AccessDeniedException
in case of JWT parsing errors. I can't find a way to map it to HTTP 401. Can it be done?
I have tried using HttpSecurity#exceptionHandling()
as well as adding an @ExceptionHandler
inside a @ControllerAdvice
, but I am always getting HTTP 403.
Solution
Thank to this thread I managed to solve it by adding the following two lines to my WebSecurityConfigurerAdapter#configure
:
.exceptionHandling()
.authenticationEntryPoint(HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
Answered By - jjrz
Answer Checked By - Robin (JavaFixing Admin)