Spring Security: how to intercept PageNotFound

2019-07-27 11:49发布

This seems to be an easy question but we couldn't find it anywhere on internet.

We're using Spring Security 3.2 and we want to be able to print the IP of the remote host whenever we get the spring message:

WARN  [org.springframework.web.servlet.PageNotFound] - No mapping found for HTTP request with URI [/page.bla] in DispatcherServlet with name 'XXX'.

How can we possibly do that?

3条回答
ゆ 、 Hurt°
2楼-- · 2019-07-27 12:06

Your problem is not related to spring-security. This log message is generated in DispatcherServlet class.

You can extend org.springframework.web.servlet.DispatcherServlet and override protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception method:

protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
    if (pageNotFoundLogger.isWarnEnabled()) {
        String requestUri = urlPathHelper.getRequestUri(request);
        pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + requestUri +"] in DispatcherServlet with name '" + getServletName() + "'");
    }
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
}

In this way you can customize logging message and add to it the ip address from HttpServletRequest parameter:

request.getRemoteAddr();

I'm not sure that it is a good practice.. but it should works.

Hope this helps!!

查看更多
Viruses.
3楼-- · 2019-07-27 12:08

This is only a partial answer; it solves the problem but not using spring security.

Create a filter that checks the status in the response (response.getStatus()). If the status code is one that you care about (for example 404 or HttpServletResponse.SC_NOT_FOUND) log a message with the details from the request that you want to store.

查看更多
你好瞎i
4楼-- · 2019-07-27 12:16

Since Spring 4.0, if you're using @ControllerAdvice, you can also enable the fact that Spring throws a NoHandlerFoundException when it detects PageNotFound by configuring the DispatcherServlet:

@Configuration
public class ApplicationConfiguration {

    @Autowired
    void configureDispatcherServlet( DispatcherServlet dispatcherServlet ) {
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    }
}

Then, in your @ControllerAdvice, you'll be able to handle this exception to return custom data:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler
    ResponseEntity<MyCustomError> handle(NoHandlerFoundException e) {

        return new ResponseEntity<>(new MyCustomError(), HttpStatus.NOT_FOUND);
    }
}
查看更多
登录 后发表回答