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?
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!!
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.
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);
}
}