【问题标题】:Is Spring Security ACL supposed to be usable with WebSecurityExpressionHandler?Spring Security ACL 是否应该与 WebSecurityExpressionHandler 一起使用?
【发布时间】:2022-02-20 22:01:57
【问题描述】:

我按照this guide 使用 ACL 设置安全性,效果很好。 之后我还尝试在 WebSecurityConfigurerAdapter 中实现 ACL。 所以我设置了一个 bean,它会创建一个 DefaultWebSecurityExpressionHandler:

    @Bean
    public DefaultWebSecurityExpressionHandler webExpressionHandler(AclPermissionEvaluator aclPermissionEvaluator) {
        final DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
        AclPermissionEvaluator permissionEvaluator = aclPermissionEvaluator();
        webSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator);
        return webSecurityExpressionHandler;
    }

我会将它应用到我的 WebSecurityConfigurerAdapter 中的 HttpSecurity:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .expressionHandler(webExpressionHandlerWithACL)
        .antMatchers(HttpMethod.PUT, "/api/user/users/{ID}").access("isAuthenticated() and hasPermission(#ID, 'xxx.xxx.xxx.xxx.xxx.UserDto', 'write')")
        .anyRequest().authenticated()
        .and()
        .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
}

但这只是行不通。这个完全相同的表达式在 @PreAuthorize 标记中起作用,但在这里它不起作用。 我调试了一下,发现准确的故障点在Spring提供的JdbcAclServiceImpl类中,方法如下:

@Override
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids)
        throws NotFoundException {
    Map<ObjectIdentity, Acl> result = this.lookupStrategy.readAclsById(objects, sids);
    // Check every requested object identity was found (throw NotFoundException if
    // needed)
    for (ObjectIdentity oid : objects) {
        if (!result.containsKey(oid)) {
            throw new NotFoundException("Unable to find ACL information for object identity '" + oid + "'");
        }
    }
    return result;
}

即使提供的参数与我使用 @PreAuthorize 标记时相同,result.containsKey(oid) 也无法在其中找到 acl,即使我可以使用调试器看到它​​并且我看到 oid 应该匹配它。

所以我的问题是: Spring Security ACL 是否应该用于保护路由,还是仅用于保护方法?

顺便说一句,我使用的是 Spring Boot 2.5.5

【问题讨论】:

    标签: spring spring-security spring-security-acl


    【解决方案1】:

    我发现了问题。类AclPermissionEvaluator 有一个方法public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) 被调用。如果我将它用作 webExpressionHandler,那么Serializable targetId 总是一个字符串。但要使其正常工作,它需要一个 Long。因此,一种解决方案是扩展AclPermissionEvaluator 并覆盖有问题的方法,以便将String 转换为Long 然后它可以工作。不要忘记然后实际使用自定义AclPermissionEvaluator

    【讨论】:

      猜你喜欢
      • 2020-04-10
      • 2014-12-20
      • 2013-01-13
      • 2014-02-15
      • 2011-07-25
      • 2021-11-26
      • 1970-01-01
      • 2015-06-18
      • 2016-09-19
      相关资源
      最近更新 更多