Issue
I've been having trouble getting security working correctly, half of the problem was fixed with this href="https://stackoverflow.com/questions/62900937/spring-boot-security-wont-ignore-certain-paths-that-dont-need-to-be-secured/62901277?noredirect=1#comment111235291_62901277">Spring Boot Security wont ignore certain paths that dont need to be secured Second problem is spring is ignoring the HTTP status code on failure and always throws a 500.
When the JWT token is invalid I want to return a 401 and a json response. I keep getting a 500 and the white label html page. JwtFilter
class JwtFilter(private val tokenService: TokenService) : GenericFilterBean() {
override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
val request = req as HttpServletRequest
val response = res as HttpServletResponse
val httpRequest = request as HttpServletRequest
val path = httpRequest.servletPath.toString().substring(0, 12)
if (path == "/api/v1/auth") {
chain.doFilter(req, res)
return
} else {
val token = TokenUtil.extractToken(request as HttpServletRequest)
if (token != null && token.isNotEmpty()) {
try {
tokenService.getClaims(token)
} catch (e: SignatureException) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid JWT Signature")
} catch (e: MalformedJwtException) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid JWT token")
} catch (e: ExpiredJwtException) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Expired JWT token")
} catch (e: UnsupportedJwtException) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unsupported JWT exception")
} catch (e: IllegalArgumentException) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Jwt claims string is empty")
}
} else {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing auth token")
}
chain.doFilter(req, res)
}
}
}
In my application class too I also have
@SpringBootApplication(exclude = [ErrorMvcAutoConfiguration::class])
Everywhere else in the application ResponseStatusException throws an error with the correct code and in JSON format, here for example when I throw an exception the response will be HTML like
<!doctype html>
HTTP Status 500 – Internal Server Error body { font-family: Tahoma, Arial, sans-serif; } h1,
h2,
h3,
b {
color: white;
background-color: #525D76;
}
h1 {
font-size: 22px;
}
h2 {
font-size: 16px;
}
h3 {
font-size: 14px;
}
p {
font-size: 12px;
}
a {
color: black;
}
.line {
height: 1px;
background-color: #525D76;
border: none;
}
</style>
HTTP Status 500 – Internal Server Error
Type Exception Report
Message 401 UNAUTHORIZED "Expired JWT token"
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.springframework.web.server.ResponseStatusException: 401 UNAUTHORIZED "Expired JWT token" events.slap.app.web.security.JwtFilter.doFilter(JwtFilter.kt:40) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92) org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
Note The full stack trace of the root cause is available in the server logs.
Apache Tomcat/9.0.35
Solution
Instead of throwing exceptions in the filter, do this
response.sendsetStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
or if you want message as well
StringBuilder sb = new StringBuilder();
sb.append("{ ");
sb.append("\"error\": \"Unauthorized\" ");
sb.append("\"message\": \"Unauthorized\"");<--- your message here
sb.append("\"path\": \"")
.append(request.getRequestURL())
.append("\"");
sb.append("} ");
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(sb.toString());
return;
Answered By - Kavithakaran Kanapathippillai
Answer Checked By - Robin (JavaFixing Admin)