Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict tomcat in spring boot to certain ip addresses

I need to restrict the embedded tomcat of a spring boot based application to certain ip addresses. I want to allow only incoming connections from two ip addresses and not all. I know how to do this in a tomcat that is not running embedded but don't know a way to configure this in spring boot. The various server.tomcat.* properties don't seem to offer support for this. There is the property server.address that enables me to bind to a local ip address, but that is not what I need.

like image 965
Marged Avatar asked Jan 02 '15 14:01

Marged


People also ask

How do I whitelist an IP address in spring boot?

We can use hasIpAddress() to allow only users with a given IP address to access a specific resource. In this configuration, only users with the IP address “11.11. 11.11” will be able to access the ”/foos” resource.

How do you restrict the endpoint of a spring boot?

Use Method-level Authorization To Restrict An Endpoint This tells Spring to check that the authenticated user has the Admin authority, and if not, deny the request. Run the app: ./gradlew bootRun . Navigate to http://localhost:8080/restricted . You'll get a 403 / Unauthorized whitepage error.


2 Answers

Found this answer searching for the same solution. This is a more accurate way of doing it within Spring Boot.

@Bean
public FilterRegistrationBean remoteAddressFilter() {

    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    RemoteAddrFilter filter = new RemoteAddrFilter();

    filter.setAllow("192.168.0.2");
    filter.setDenyStatus(404);

    filterRegistrationBean.setFilter(filter);
    filterRegistrationBean.addUrlPatterns("/*");

    return filterRegistrationBean;

}

The default response is a 403. To change that to a 404 this is added filter.setDenyStatus(404);

You can also set Deny addresses instead with filter.setDeny("192\\.168\\.0\\.2");

RemoteAddressFilter Docs for Tomcat

like image 145
code Avatar answered Oct 19 '22 22:10

code


If you want to add multiple IP addresses then you can do that by using Spring Security with a custom Authentication Provider. The custom Authentication Provider configuration is as follows:

@Component
public class CustomIpAuthenticationProvider implements AuthenticationProvider {

   Set<String> whitelist = new HashSet<String>();

    public CustomIpAuthenticationProvider() {
        whitelist.add("103.219.56.22");
        whitelist.add("192.168.2.33");
    }

    @Override
    public Authentication authenticate(Authentication auth) throws AuthenticationException {

        WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
        String userIp = details.getRemoteAddress();

        if(! whitelist.contains(userIp)) {
            throw new BadCredentialsException("Invalid IP Address");
        }
    }
}

And the Spring Security configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomIpAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.authenticationProvider(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
          .antMatchers("/login").permitAll()
          .anyRequest().authenticated()
          .and().formLogin().permitAll()
          .and().csrf().disable();
    }

}

Or if you want only some particular mappings to be accessed from some specific IP addresses then the Spring Security configuration is as follows:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
          .antMatchers("/login").permitAll()
          .antMatchers("/rockstar/**").hasIpAddress("103.219.55.22")
          .anyRequest().authenticated()
          .and()
          .formLogin().permitAll()
          .and()
          .csrf().disable();
    }
}
like image 39
sam Avatar answered Oct 19 '22 23:10

sam