首页 > 解决方案 > Spring Security hasRole() 用于未经身份验证的用户,考虑角色层次结构

问题描述

我的 Spring Boot 2 + Spring Security 应用程序中有一个角色层次结构:

@Bean
public RoleHierarchy roleHierarchy() {
    var rh = new RoleHierarchyImpl();
    rh.setHierarchy("ROLE_ADMIN > ROLE_USER and ...");

    return rh;
}

现在我(作为管理员)想代表另一个用户创建一个实体,但我应该检查该用户是否具有基于上述层次结构的特定权限。

我知道可以为当前经过身份验证的用户调用 spring security hasRole(),但就我而言,我要授权的用户未经过身份验证。

现在,我可以检查用户是否具有该特定权限:

public boolean hasAuthority(User user, String authority) {
    return user.getAuthorities()
            .stream()
            .anyMatch(grantedAuthority -> grantedAuthority.getName().equals(authority));
}

但是这样一来,相当长的层次结构就会被忽略。

如果有任何帮助,我将不胜感激。

标签: javaspringspring-bootspring-security

解决方案


您可以使用角色层次结构,请参阅RoleHierarchy#getReachableGrantedAuthorities

Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(Collection<? extends GrantedAuthority> authorities) 

返回所有可访问权限的数组。

可达权限是直接分配的权限加上角色层次结构中可(传递)访问的所有权限。

示例:角色层次结构:ROLE_A > ROLE_B 和 ROLE_B > ROLE_C。
直接分配的权限:ROLE_A。
可达权限:ROLE_A、ROLE_B、ROLE_C。

参数:

authorities- 直接分配的权限列表。

回报:

给定指定权限的所有可访问权限的列表。

您修改后的代码:

public boolean hasAuthority(User user, String authority) {
    return roleHierarchy()
        .getReachableGrantedAuthorities(user.getAuthorities())
        .stream()
        .anyMatch(grantedAuthority -> grantedAuthority.getName().equals(authority));
}

推荐阅读