Spring Security 配置中的单角色多 IP 地址

Posted

技术标签:

【中文标题】Spring Security 配置中的单角色多 IP 地址【英文标题】:Single role multiple IP addresses in Spring Security configuration 【发布时间】:2017-11-02 07:45:34 【问题描述】:

在我的 Spring Boot 项目中,我试图向具有特定 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

我的请求网址:http://localhost:9595/admin/checkappeals/211

【问题讨论】:

我收到以下错误:HTTP Status 403 -message- description 对指定资源的访问已被禁止。 【参考方案1】:

您的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:

请注意,匹配器是按顺序考虑的。因此,以下是无效的,因为第一个匹配器匹配每个请求并且永远不会到达第二个映射:

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

【讨论】:

很奇怪,在这个发布的那天我遇到了同样的问题。你知道有什么方法可以让它作为一个列表工作吗?我的问题是需要授权的 IP 地址数量未知(将从配置文件中读取),因此每个 IP 在访问参数内的解决方案不起作用。谢谢 @haddow64:使用 StringBuilder(或类似的东西)并在 for 循环中连接条件。完整的条件使用如antMatchers("/admin/**").access(condition)【参考方案2】:

您可以通过以下方式将逗号分隔的 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;

【讨论】:

以上是关于Spring Security 配置中的单角色多 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章

具有角色的经过身份验证的用户的 Spring Security Java 配置

Spring Security 3.2 - 配置全局方法安全性以使用角色层次结构

认证与授权Spring Security的授权流程

认证与授权Spring Security的授权流程

Spring Security按角色获取用户列表

Spring Security基于动态角色资源权限校验