spring 如何要求多个角色/权限

g6baxovj  于 2023-01-12  发布在  Spring
关注(0)|答案(5)|浏览(145)

据我所知,@Secured注解或ExpressionUrlAuthorizationConfigurer对象中只有 any of 列表可用,尝试添加多个注解或hasAuthority()调用要么编译失败,要么只使用最新的一个。
我如何定义一个特定的请求(一组与模式匹配的请求)或方法需要一个角色/权限列表的 * 全部 *?

erhoui1w

erhoui1w1#

最好的解决办法似乎是

@PreAuthorize("hasRole('one') and hasRole('two') and ...")

没有什么好的方法来使用常量,比如@Secured

kmb7vmvb

kmb7vmvb2#

您似乎正在使用:hasAuthority([authority])。这只需要一个权限。请改用hasAnyAuthority([authority1,authority2])。这允许您一次指定多个权限,并且可以在授权中考虑任何权限。参考spring官方文档here。只需在页面中找到文本:hasAnyAuthority([authority1,authority2])
例如,在控制器方法上,添加:@PreAuthorize("hasAnyAuthority('permission1','permission2')")

eoigrqb6

eoigrqb63#

在Spring Security 5.5中,您可以在使用AuthorizeHttpRequestsConfigurer时使用自定义AuthorizationManager

public class DelegatingMultiAuthorizationManager<T> implements AuthorizationManager<T> {
    private final List<AuthorizationManager<T>> authorizationManagers;

    public DelegatingMultiAuthorizationManager(List<AuthorizationManager<T>> authorizationManagers) {
        this.authorizationManagers = authorizationManagers;
    }

    public static <T> DelegatingMultiAuthorizationManager<T> hasAll(AuthorizationManager<T>... authorizationManagers) {
        Assert.notEmpty(authorizationManagers, "authorizationManagers cannot be empty");
        Assert.noNullElements(authorizationManagers, "authorizationManagers cannot contain null values");
        return new DelegatingMultiAuthorizationManager(Arrays.asList(authorizationManagers));
    }

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
        for (AuthorizationManager<T> authorizationManager : authorizationManagers) {
            AuthorizationDecision decision = authorizationManager.check(authentication, object);
            if (decision == null || !decision.isGranted()) {
                return new AuthorizationDecision(false);
            }
        }

        return new AuthorizationDecision(true);
    }
}

此AuthorizationManager要求每个提供的AuthorizationManager授予访问权限。如果其中任何一个未授予访问权限,则授权将失败。
然后可以像这样使用它(也允许使用常量):

http.authorizeHttpRequests(authorize -> authorize
            .antMatchers("/something/*")
                .access(DelegatingMultiAuthorizationManager
                                .hasAll(AuthorityAuthorizationManager.hasAuthority("auth_a"),
                                        AuthorityAuthorizationManager.hasAuthority("auth_b")))
rvpgvaaj

rvpgvaaj4#

作为端点范围的解决方案,您只需使用

.antMatchers("/user/**").access("hasAuthority('AUTHORITY_1') and hasAuthority('AUTHORITY_2')")

我只在两个权威机构做过测试,但我想你可以而且-不止两个。

ne5o7dgx

ne5o7dgx5#

您可以像使用.hasAnyAuthority("manager", "customer");一样使用hasAnyAuthority

相关问题