Spring security, error 405 with protecting current post method - spring-mvc

I use spring security with roles to protect current pages or actions with their own addresses of my application. With access denied page i can catch page of error 403 (access denied) when user tries to
get not allowed page, but when i protect current action, like this:
<form th:action="'/blog/'+${el.id}+'/remove'" method="post">
<button class = "btn btn-warning" type="submit">Delete</button>
</form>
With current controller's method:
#PostMapping("/blog/{id}/remove")
public String blogPostRemove(#PathVariable(value = "id") long postId, Model model) {
Post post = postRepository.findById(postId).orElseThrow();
postRepository.delete(post);
return "redirect:/blog";
}
When user with not allowed role tries to act he will get page with error 405:
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'POST' not supported. User with allowed role doesn't have any problem. There is a WebSecurityConfig code:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/unpublished","/blog/*/remove","/blog/*/comments/*/remove")
.hasAuthority("ADMIN")
.antMatchers("/blog/*/edit","/blog/*/comment","/blog/add").authenticated()
.antMatchers("/","/registration","/login","/blog/*").permitAll()
.and().formLogin()
.loginPage("/login")
.and().exceptionHandling()
.accessDeniedPage("/access-denied");
http.csrf().disable();
}
}
How can i change this page with my /access-denied?
Logs:
2020-07-13 11:26:58.094 DEBUG 42636 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/blog/28", parameters={}
2020-07-13 11:26:58.096 DEBUG 42636 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.springExample.controllers.BlogController#blogDetails(long, Model)
2020-07-13 11:26:58.364 DEBUG 42636 --- [nio-8080-exec-6] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, *//*;q=0.8]
2020-07-13 11:26:58.402 DEBUG 42636 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK
2020-07-13 11:27:04.814 DEBUG 42636 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for POST "/access-denied", parameters={}
2020-07-13 11:27:04.816 WARN 42636 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
2020-07-13 11:27:04.817 DEBUG 42636 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 405
2020-07-13 11:27:04.818 DEBUG 42636 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for POST "/error", parameters={}
2020-07-13 11:27:04.818 DEBUG 42636 --- [nio-8080-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2020-07-13 11:27:04.831 DEBUG 42636 --- [nio-8080-exec-9] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2020-07-13 11:27:04.838 DEBUG 42636 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 405

I located the problem - when user tries to act, he will send post method from form. When application catches an access-denied error, it will try to get /access-denied page, but due to action type, it will be post request. Solution is to add PostMapping function of /access-denied page to the current controller:
#GetMapping("/access-denied")
public String blockAccess(Model model) {
return "access-denied";
}
#PostMapping("/access-denied")
public String actionAccess(Model model) {
return "access-denied";
}

Related

.NET 5 WebApi Error Handling NotFound Behaving Strangely

I have a WebAPI app which has registered a custom exception handler with:
app.UseExceptionHandler("/error");
I then have an ErrorController with the following code:
[Route("/error")]
public IActionResult Error()
{
if (...)
return Problem(detail: "Text", statusCode: 403);
else
return NotFound();
}
This is obviously simplified.
The problem is that with 403 or any other code I've tried (apart from 404) this works fine.
With 404 (whether passed to Problem or using NotFound directly) I get a new exception raised caused by the system attempting to copy the original exception to a stream:
System.Net.Http.HttpRequestException : Error while copying content to a stream.
---- System.IO.IOException ...
Any thoughts?

use #ControllerAdvice and #ExceptionHandler but still also allow for the default exception mapping

When i use a #ControllerAdvice with the #ExceptionHandler annotation then none of the normal exception handling works anymore. All results in a HTML page with the title "HTTP Status 500 – Internal Server Error" and nothing is logged in the console.
I've created a simple #ControllerAdvice as below, when this didn't work as expected i started trying with the basePackages and extending from ResponseEntityExceptionHandler.
#ControllerAdvice(basePackages = "nl.xxxx.events")
public class EventExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(EventExceptionHandler.class);
#ResponseStatus(HttpStatus.NOT_FOUND)
#ExceptionHandler(EventNotFoundException.class)
public void handlePersonNotFound(RuntimeException ex) {
logger.error("error", ex);
}
}
In the service i throw the exception using:
public Event findById(Long id) {
return this.eventRepository.findById(id).orElseThrow(() -> new EventNotFoundException(id));
}
I've tried to compare the flow of code with and without #ControllerAdvice but there are numerous things that are different. For example without the #ControllerAdvice the value attribute of the HttpEntityMethodProcessor is set with the an object describing the exception. But with the #ControllerAdvice this attribute is always null.
I expected the code above to not interfere with the normal exception handling.
As a example i'd like to use the "could not initialize proxy - no Session" error because this is easy for me to reproduce.
Before i added the #ControllerAdvice spring gave the following json result:
{"timestamp":"2019-06-02T19:17:14.223+0000","status":500,"error":"Internal Server Error","message":"Could not write JSON: failed to lazily initialize a collection of role: (truncated)....","path":"/events/find"}
and with debug logging:
2019-06-02 21:18:29.723 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.724 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:18:29.729 WARN 1588 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.730 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Sun Jun 02 21:18:29 CEST 2019, status=500, error=Internal Server Error, message=Could not (truncated)...]
2019-06-02 21:18:29.732 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 500
But now it returns:
<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1></body></html>
And with debug logging:
2019-06-02 21:20:33.682 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:20:33.688 DEBUG 22308 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:20:33.760 INFO 22308 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-06-02 21:20:33.900 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:20:33.901 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:20:33.923 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using #ExceptionHandler public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception
2019-06-02 21:20:33.925 DEBUG 22308 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : No match for [application/json, text/plain, */*], supported: []
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
So, at some point it just says No match for [application/json, text/plain, */*], supported: [] and wont return a nice JSON exception anymore.
Any ideas at what i'm doing wrong? initially is just want EventNotFoundException to result in a 404 instead of a 500. Propably in the future i'd like to add content aswell.
The problem is that you try to handle RuntimeException which is too general. public void handlePersonNotFound(RuntimeException ex) You also don't need to extend from ResponseEntityExceptionHandler.
If you write an ExceptionHandler that should handle a specific exception, the handleException method needs to accept that specific exception as parameter. Also you would probably want some sort of repsonse.
#ControllerAdvice
public class EventExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(getClass());
#ResponseBody
#ResponseStatus(HttpStatus.NOT_FOUND)
#ExceptionHandler(EventNotFoundException.class)
public String handlePersonNotFound(EventNotFoundException ex) {
logger.error("error", ex);
return ex.getMessage();
}
}
This will give a basic reponse body with the exception message and error code.

Spring Rest Controller method not invoked with path variable and http request as arguments

This is my controller method
#RestController
public class ProfileController {
#GetMapping("/quiz/{quizId}/identifyfromsixjson")
#ResponseBody
UserProfileQuestion playIdentifyFromSix(#PathVariable String quizId, HttpServletRequest request) {
... Calling service method ... here
}
}
application.properties
server.contextPath=/myproject
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
So when I make a GET request to http://localhost:8080/myproject/identifyfromsixjson/test, this is the response I see in Postman.
{
"timestamp": "2018-10-08T02:42:14.387+0000",
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'GET' not supported",
"path": "/myproject/quiz/test/identifyfromsixjson"
}
Startup logs
018-10-08 01:59:32.603 WARN 46035 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2018-10-08 01:59:32.641 INFO 46035 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/quiz/{quizId}/identifyfromsixjson]}" onto public org.springframework.http.ResponseEntity<com.myproject.model.UserProfileQuestion> com.myproject.controller.ProfileController.fetchUserProfileAndHeadShot(java.lang.String,javax.servlet.http.HttpServletRequest)
2018-10-08 01:59:32.644 INFO 46035 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-10-08 01:59:32.644 INFO 46035 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-10-08 01:59:32.672 INFO 46035 --- [ main] o.s.w.s.h.BeanNameUrlHandlerMapping : Mapped URL path [/myproject] onto handler '/myproject'
2018-10-08 01:59:32.678 INFO 46035 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-08 01:59:32.678 INFO 46035 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
What am I doing wrong?
This is the path you've defined:
/quiz/{quizId}/identifyfromsixjson
and this is the path you're testing with
/identifyfromsixjson/test
It should be apparent that they don't match, which is why you're getting that error.
You can do the following:
1. Test with the path that you've defined:
http://localhost:8080/myproject/quiz/test/identifyfromsixjson
2. Update your path definition
#GetMapping("/identifyfromsixjson/{quizId}")
#ResponseBody
UserProfileQuestion playIdentifyFromSix(#PathVariable String quizId,HttpServletRequest request) {
... Calling service method ... here
}
and then test with
http://localhost:8080/myproject/identifyfromsixjson/test
Looks like you want to write a RestController. Annotate your controller with #RestController
#RestController
public class QuizController {
#GetMapping("/identifyfromsixjson/{quizId}")
#ResponseBody
UserProfileQuestion playIdentifyFromSix(#PathVariable String quizId, HttpServletRequest request) {
... Calling service method ... here
}
}

Spring ServletRegistrationBean not loaded in JUnit Test

I'm trying to test a Rest Service in my Spring Boot Application.
I can do ir successfully when I run or debug the whole application. Spring Bott start shows the following lines, among others:
2015-07-02 17:04:10.654 INFO 3084 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.20
2015-07-02 17:04:10.769 INFO 3084 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2015-07-02 17:04:10.769 INFO 3084 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2449 ms
2015-07-02 17:04:11.219 INFO 3084 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2015-07-02 17:04:11.224 INFO 3084 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2015-07-02 17:04:11.224 INFO 3084 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
However, when I run my JUnit test, everything works fine, request mappings work, etc, except that the servlet is not initialized. Indeed, those lines above do not appear.
That's strange, because I'm running the test using the same Application.class which I use to run the whole application. This is Application.class:
#ImportResource("classpath:/META-INF/spring/integration/spring-integration-context.xml")
#SpringBootApplication
#WebAppConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
And from my JUnit test:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
public class CatalogRestControllerTests extends AbstractTransactionalJUnit4SpringContextTests {
...
#Test
public void someTest() {...}
}
I've been trying to fix the problem from servlet-context.xml and web.xml configuration files. But I don't think the problem is there, since it works for Application.class
Any idea?
Thank you!
Found it.
So it seems I was missing #WebIntegrationTest annotation on my JUnit class. This is what documentation says about #WebIntegrationTest:
Test class annotation signifying that the tests are "web integration
tests" and therefore require full startup in the same way as a
production application (listening on normal ports). Normally used in
conjunction with #SpringApplicationConfiguration,
This annotation can be used as an alternative to #IntegrationTest and
#WebAppConfiguration.

Spring filters cannot see status codes for requests to static pages

I'm running a Spring Boot Web MVC app which has some pages handled by controllers, and others (static content) configured using a ResourceHandler. I've got my own error handling for the controller methods. I'm running it under standalone Tomcat.
I want to log every HTTP request and its response, and the HTTP status codes of the responses. Using Tomcat access logs isn't an option because there is a context for each request (client has an active session) and I want to correlate sessions with pages requested.
I've tried logging using both filters and interceptors. The problem is that I can't make interceptors see any requests to static resources - I think they only work for pages that are handled by controllers - and the filters will log requests to static resources but they always log the response as 200, even when it's a 404. I haven't got my own default error page set up (and I'm not that interested in setting one, I just need to set the status) so when I request a static resource that doesn't exist I'll see something like this in my logs:
2015-03-26 16:02:46.770 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=request; Method=GET; resource=/resources/missing.html
2015-03-26 16:02:46.770 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=response; Status=200; Length=unknown; resource=/resources/missing.html
2015-03-26 16:02:46.788 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=request; Method=GET; resource=/error
2015-03-26 16:02:46.788 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=response; Status=404; Length=unknown; resource=/error
2015-03-26 16:02:46.811 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.a.c.RequestLoggingInterceptor : CONTEXT=unknown; Type=request; Method=GET; resource=/error
2015-03-26 16:02:46.839 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.a.c.RequestLoggingInterceptor : CONTEXT=unknown; Type=response; Status=404; Length=unknown; resource=/error
As you can see, only the filter picks up any request/response for a static resource, but both filter and interceptor later pick up the request and response for my missing /error page.
Note that I have this issue, but as far as I know it's only affecting DeferredResults - it shouldn't be affecting the appearance of the status in the filter chain for a static page request.
How can I log the real response status for requests to missing static resources? I don't really mind how this is accomplished - through filters or using interceptors or by overriding the controller for /error.
Here's my AppConfiguration which adds the static resource handlers and the interceptors:
#Configuration
#EnableConfigurationProperties
#EnableWebMvc
public class AppConfiguration extends WebMvcConfigurerAdapter {
#Autowired
private MyAppProperties properties;
#Autowired
SessionDataArgumentResolver sessionDataArgumentResolver;
// Serve up static files directly from the external directory
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
properties.getExternalDirectoryURI("resources/").toString()).setCachePeriod(
properties.getCacheControlMaxAge());
// At least after the controller registry
registry.setOrder(10);
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(sessionDataArgumentResolver);
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestLoggingInterceptor());
}
}
I ended up posting an issue on Github: https://github.com/spring-projects/spring-boot/issues/2817
The answer was embarrassingly simple: I needed to log the response status after invoking filterChain.doFilter:
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(request, response);
LOGGER.info("HTTP request for resource {} - status {}", request.getRequestURI(), response.getStatus());
}
It works perfectly after doing that.

Resources