Closed chpasha closed 6 months ago
Not sure I understand the request. The library does handle AccessDeniedException
. I wrote a test just now for it, see https://github.com/wimdeblauwe/error-handling-spring-boot-starter/commit/6f8cdaba58a4d9101befd227c427952473d290f5
Let me know if I am missing something in your request.
I think, you current test implementation doesn't completely resemble how the Spring security works in this case. Change you test security chain and specify that rest method needs some role, for instance
http.authorizeHttpRequests()
.requestMatchers("/test/spring-security/access-denied")
.hasAuthority("AASSSS")
your test will fail, but 403 will be returned
MockHttpServletResponse:
Status = 403
Error message = Forbidden
Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"0", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: No value at JSON path "code"
now modify exception handling adding accessDeniedHandler
http.exceptionHandling()
.authenticationEntryPoint(unauthorizedEntryPoint)
.accessDeniedHandler(((request, response, ex)
-> {
unauthorizedEntryPoint.commence(request, response, new InsufficientAuthenticationException(ex.getMessage(), ex));
response.setStatus(HttpStatus.FORBIDDEN.value());
}));
I abuse here your unauthorizedEntryPoint - the test will still fail, but now the framework does return JSON, just the wrong error code, but the rest is fine (response status and message)
MockHttpServletResponse:
Status = 403
Error message = null
Headers = [Content-Type:"application/json;charset=UTF-8", X-Content-Type-Options:"nosniff", X-XSS-Protection:"0", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = application/json;charset=UTF-8
Body = {"code":"UNAUTHORIZED","message":"Access Denied"}
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: JSON path "code" expected:<ACCESS_DENIED> but was:<UNAUTHORIZED>
Expected :ACCESS_DENIED
Actual :UNAUTHORIZED
My assumption is, AccessDeniedException is not thrown directly, but rather default accessDeniedHandler is used (probably AccessDeniedHandlerImpl), which will (again probably) try to redirect/forward somewhere but will not throw exception, so it won't be caught. Perhaps there is some possibility to make spring security throw accessdeniedexception, but not by default.
Thanks for that info. I added a second test now, and an implementation of AccessDeniedHandler
that can be used now.
Great, thank you :-)
Exceptions, that are thrown if the user is authenticated, but lacks some required role, are not caught now. To fix that, we have to also set the accessDeniedHandler in security config exceptionHandling. Its implementation could be actually 99.9% the same as UnauthorizedEntryPoint except for returned http response status (which should be forbidden) and the type of exception