Spring Security 6.x 已弃用 AccessDecisionVoter

问题描述 投票:0回答:2

在 Spring Boot 2.7.x 中,我使用了

RoleHierarchyVoter

public RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    roleHierarchy.setHierarchy("ROLE_ADMINISTRATOR > ROLE_USER > ROLE_GUEST");
    return roleHierarchy;
}

@Bean
public RoleHierarchyVoter roleVoter() {
    return new RoleHierarchyVoter(roleHierarchy());
}

在 Spring Boot 3.x 中,

AccessDecisionVoter
已弃用 - 建议使用
AuthorizationManager
。是否有可能使用 AuthorizationManager-Implementation 来设置角色层次结构?

的用法
@Bean
AccessDecisionVoter hierarchyVoter() {
    RoleHierarchy hierarchy = new RoleHierarchyImpl();
    hierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER" +
            "ROLE_USER > ROLE_GUEST");
    return new RoleHierarchyVoter(hierarchy);
}

自从我使用

AuthorizationFilter
后就不起作用了。

spring spring-boot spring-security
2个回答
2
投票

只需暴露一个

expressionHandler
bean 就可以完成这项工作。

如果您使用方法安全性(

@EnableMethodSecurity
):

@Bean
public RoleHierarchyImpl roleHierarchy() {
    final RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST");
    return roleHierarchy;
}

@Bean
public DefaultMethodSecurityExpressionHandler expressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setRoleHierarchy(roleHierarchy());
    return expressionHandler;
}

如果您使用网络安全 (

@EnableWebSecurity
) :

@Bean
public RoleHierarchyImpl roleHierarchy() {
    final RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST");
    return roleHierarchy;
}

@Bean
public DefaultWebSecurityExpressionHandler expressionHandler() {
    DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
    expressionHandler.setRoleHierarchy(roleHierarchy());
    return expressionHandler;
}

编辑

setHierarchy
自 7.0 起已弃用,您现在可以直接使用 :

return RoleHierarchyImpl.fromHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_USER > ROLE_GUEST");

0
投票

首先,创建

AuthorizationManager
的实例:

var access = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("USER");

此实例将用于授权我们的端点。因此,在

hasRole
方法中,提供您想要用于保护特定端点的一个或多个角色的名称。

其次,定义角色层次结构:

var hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");

在本例中,我们定义

ROLE_ADMIN
位于
ROLE_USER
之上,因此
ROLE_ADMIN
ROLE_USER
具有相同的作用。

第三,我们在

RoleHierarcy
实例中设置
AuthorizationManager
实例:

access.setRoleHierarchy(hierarchy);

最后,我们在路由保护配置中设置

AuthorizationManager
实例。所以所有的代码在一起看起来像这样:

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        var access = AuthorityAuthorizationManager.<RequestAuthorizationContext>hasRole("USER");
        var hierarchy = new RoleHierarchyImpl();
        hierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
        access.setRoleHierarchy(hierarchy);

        http.authorizeHttpRequests(authorize -> authorize.anyRequest().access(access));

        return http.build();

    }
© www.soinside.com 2019 - 2024. All rights reserved.