uksz
uksz

Reputation: 18719

Spring Security hasIpAddress causes errors

In my configuration, I have defined that:

@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)

And with the following code:

    http.exceptionHandling()
            .authenticationEntryPoint(authEntryPoint)
            .and()
            .authorizeRequests()
            .antMatchers("/api/payment").permitAll()
            //.antMatchers("/api/payment").hasIpAddress("XXX.XXX.X.XX")
...

Now, when I have permited all traffic to '/api/payment', everything gets executed.

However, if I try to enable the IP verification:

    http.exceptionHandling()
            .authenticationEntryPoint(authEntryPoint)
            .and()
            .authorizeRequests()
            //.antMatchers("/api/payment").permitAll()
            .antMatchers("/api/payment").hasIpAddress("XXX.XXX.X.XX")
...

The requests send from the given IP address receive the following response:

{"errorMessage":"Not Found","errorId":"6ae34aa3-9195-42d6-8906-996906988ce0","errorDetails":null} 

What am I doing wrong?

EDIT

This is the method that I am invoking:

@RequestMapping(value = "/payment", method = POST)
public String saveOrder(@ModelAttribute PaymentDto paymentDto) {
    paymentService.savePayment(paymentDto);
    return "OK";
}

Since I always send request data (for example, the post is on the following url: api/payment?id=123&whatever)

I've added:

.antMatchers("/api/payment?**").access("hasIpAddress('XXX.XXX.X.XX')")

But this didn't worked neither.

UPDATE 2

I've changed placement of my antMatcher like this:

http.exceptionHandling()
        .authenticationEntryPoint(authEntryPoint)
        .and()
        .authorizeRequests()
        .antMatchers("/", "/app/**", "/assets/**", "/fonts/**", "/images/**").permitAll()
        .antMatchers("/authentication/login", "/login.html").anonymous()
        .antMatchers("/api/products/**").permitAll()
        .antMatchers("/api/cities/**").permitAll()
        .antMatchers("/api/order/**").permitAll()
        .antMatchers("/api/payment").hasIpAddress("XXX.XXX.X.XX")
        .anyRequest().authenticated()
        .and()
        .csrf().requireCsrfProtectionMatcher(new CsrfRequestMatcher())
        .and()
        .formLogin()
        .loginPage("/login.html")
        .loginProcessingUrl("/authentication/login")
        .successHandler(authSuccessHandler)
        .failureHandler(authFailureHandler)
        .and()
        .logout()
        .logoutUrl("/authentication/logout")
        .logoutSuccessHandler(logoutSuccessHandler)
        .deleteCookies(JSESSIONID_COOKIE, CSRF_COOKIE)
        .invalidateHttpSession(true)
        .permitAll();

Which now just redirects me to the login page when I am trying to make a post from the given Ip Address

Upvotes: 1

Views: 2328

Answers (1)

uksz
uksz

Reputation: 18719

So as I turned out, I was receiving the request via proxy from nginx, which wasn't passing the original IP address of a requester. I had to add some additional nginx configuration, and now, I can verify IP address like this:

@RequestMapping(value = "/payment", method = POST)
public String saveOrder(PaymentDto paymentDto, HttpServletRequest request) {
    if (request.getHeader("X-Forwarded-For").equals("XXX.XXX.X.XX")){
      DO STUFF
    }
}

Upvotes: 2

Related Questions