In my Spring Boot project I am trying to give access to several admin users with specific IP address.
Is it possible to map a single role to multiple IP addresses?
Here is the code from my security configuration which didn't work. (I am giving hard coded role name and ip addresses for simplicity)
@SuppressWarnings("ALL")
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
List<String> ipAddresses = new ArrayList<>();
ipAddresses.add("127.0.0.1");
ipAddresses.add("192.168.1.0/24");
ipAddresses.add("0:0:0:0:0:0:0:1");
for (String ip : ipAddresses) {
http.authorizeRequests().
antMatchers("/admin" + "/**")
.access("hasRole('admin') and hasIpAddress('" + ip + "')");
}
}
//some other configurations
}
URL of my request: http://localhost:9595/admin/checkappeals/211
configure. Deprecated. Used by the default implementation of authenticationManager() to attempt to obtain an AuthenticationManager . If overridden, the AuthenticationManagerBuilder should be used to specify the AuthenticationManager .
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.
If you are using Spring and Spring Security WITHOUT Spring Boot, The @EnableWebSecurity does just you described in your original question: it will automatically define and configure several beans, the filter chain, etc. to enable basic security for a web application.
It allows configuring things that impact all of web security. WebSecurityConfigurerAdapter is a convenience class that allows customization to both WebSecurity and HttpSecurity. We can extend WebSecurityConfigurerAdapter multiple times (in distinct objects) to replicate the behavior of having multiple http elements.
Your for
loop results in following configuration:
@SuppressWarnings("ALL")
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('admin') and hasIpAddress('127.0.0.1')")
.antMatchers("/admin/**").access("hasRole('admin') and hasIpAddress('192.168.1.0/24')")
.antMatchers("/admin/**").access("hasRole('admin') and hasIpAddress('0:0:0:0:0:0:0:1')");
}
//some other configurations
}
So for URL:
http://localhost:9595/admin/checkappeals/211
only the first matcher is considered, see HttpSecurity#authorizeRequests:
Note that the matchers are considered in order. Therefore, the following is invalid because the first matcher matches every request and will never get to the second mapping:
http.authorizeRequests().antMatchers("/**").hasRole("USER").antMatchers("/admin/**") .hasRole("ADMIN")
You have to build something like:
http
.authorizeRequests()
.antMatchers("/admin/**").acces("hasRole('admin') and (hasIpAddress('127.0.0.1') or hasIpAddress('192.168.1.0/24') or hasIpAddress('0:0:0:0:0:0:0:1'))";
This is how you can join your comma separated ips into an expression for the .access() method:
private String createHasIpRangeExpression() {
String ipRanges= "127.0.0.1,192.168.1.0/24,0:0:0:0:0:0:0:1"
List<String> validIps = Arrays.asList(ipRanges.split("\\s*,\\s*"));
String hasIpRangeAccessExpresion = validIps.stream()
.collect(Collectors.joining("') or hasIpAddress('", "hasIpAddress('","')"));
return hasIpRangeAccessExpresion;
}
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