3
votes

I have Spring MVC app, hosted in Tomcat container. Tomcat is fronted with NginX, and because of that I set explcitly the header in NginX configuration:

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

This seems to be working OK, the header is there (I see it in the debugger).

Now, I tried to follow this solution here, with the request wrapping and filter, but it does not work, as apparently my custom-wrapped request object is not the one used by MVC mechanism. Mappings are as follows:

 <servlet-mapping>  
   <servlet-name>mvc-dispatcher</servlet-name>  
   <url-pattern>/</url-pattern>  
 </servlet-mapping>

 <filter-mapping>
   <filter-name>RealIPFilter</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>

I try to extract remote address in two (different) places in the code:

1)

public class PostAuthSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response, 
            Authentication authentication)
    throws IOException, ServletException {
           // here
           request.getRemoteAddr();
    }
}

and
2)

public class LoginFailureEventListenter implements
ApplicationListener<AuthenticationFailureBadCredentialsEvent> {

    @Override
    public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {
        String remoteIP = null;
        Object src = event.getSource();
        if(src instanceof UsernamePasswordAuthenticationToken) {
            UsernamePasswordAuthenticationToken upat = (UsernamePasswordAuthenticationToken) src;
            if(upat.getDetails() instanceof WebAuthenticationDetails) {
                // here
                remoteIP = ((WebAuthenticationDetails)upat.getDetails()).getRemoteAddress();
            }
        }
}

What could be the proper way to go about this with Spring MVC ?

EDIT
Since the application is secured with Spring security, this may as well be related only to making Spring security accept wrapped request, or apply this filter as a first filter in the processing chain, or something to that effect (if at all possible).

1
Make sure that your wrapping occurs BEFORE spring security. Move the filter-mapping element containing yuor wrapping filter before the filter-mapping for spring security. - M. Deinum
Yeah, seems like I answered my own question with the edit. Just tried it, and it works <custom-filter position="FIRST" ref="realIPFilter" />. Would you care to give an answer that I can accept, since your suggestion seems valid ? - Less
Your filter doesn't have to be part of the spring security filter chain, you can simply define it in the web.xml and make sure it executes before spring security's filter chain. - M. Deinum
How do I do that (how to specify the order in web.xml) ? If this is just determined by the order in the XML file, I tried it, it does not work... - Less
Correction - it works. I must have forgotten to restart the server or did something wrong. - Less

1 Answers

1
votes

Make sure that your wrapping occurs BEFORE spring security. Move the filter-mapping element containing yuor wrapping filter before the filter-mapping for spring security.