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.
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.
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.
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
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With