Spring 安全配置中的单一角色多个 IP 地址

Single role multiple IP addresses in Spring Security configuration

在我的 Spring 引导项目中,我试图授予多个具有特定 IP 地址的管理员用户的访问权限。

是否可以将单个角色映射到多个 IP 地址?

这是我的安全配置中的代码,它不起作用。 (为了简单起见,我给出了硬编码的角色名称和 IP 地址)

@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 我的要求:http://localhost:9595/admin/checkappeals/211

您的 for 循环导致以下配置:

@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
}

因此 URL:

http://localhost:9595/admin/checkappeals/211

只考虑第一个匹配器,参见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")

您必须构建如下内容:

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

这是将逗号分隔的 ips 连接到 .access() 方法的表达式中的方法:

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;
}