Search code examples
javasecurityspring-bootspring-securityip-address

Single role multiple IP addresses in Spring Security configuration


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


Solution

  • 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'))";