当前位置: 首页 > 知识库问答 >
问题:

在Spring Security中实现分层角色

司徒兴思
2023-03-14

我试图在Spring security中实现分层角色,并根据Spring源代码文档在xml文件中添加了以下配置

<bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_ADMIN > ROLE_PRO
            ROLE_PRO > ROLE_PREMIUM
            ROLE_PREMIUM > ROLE_BASIC
            ROLE_BASIC > ROLE_ANONYMOUS
        </value>
    </property>
</bean>

 <bean id="roleVoter"
        class="org.springframework.security.access.vote.RoleHierarchyVoter">
         <constructor-arg ref="roleHierarchy"/>
</bean>

我已经尝试了上面的行,但是当ROLE_ADMIN试图访问分配给role_basic的url时,我被拒绝访问。我还需要添加更多的东西吗。我在Spring网站上除了那些线之外,什么也没有找到。此外,如果您知道分层角色的任何良好实现,请务必提及它们。

共有1个答案

冯宏恺
2023-03-14

我认为您需要在AccessDecisionManager上注册RoleVoter。@见此答案示例。

但老实说,我对Spring分级投票人概念表示怀疑,因为你需要在任何地方添加一个特殊的分级投票人。我个人更喜欢另一种方式:我实现了一个自定义jdbcdaoimpl,它覆盖了AddCustomAuthorities,并将“普通”角色添加到“现有”中一次。

/**
 * Extension of {@link JdbcDaoImpl} User Detail Provider, so that is uses the
 * {@link PrivilegesService} to extend the provided Authorities.
 *
 */
public class JdbcDaoPrivilegesImpl extends JdbcDaoImpl {

    private PrivilegesService privilegesService;

    public JdbcDaoPrivilegesImpl(final PrivilegesService privilegesService) {        
        this.privilegesService = privilegesService;
    }

    @Override
    protected void addCustomAuthorities(String username, List<GrantedAuthority> authorities) {
        super.addCustomAuthorities(username, authorities);         

        List<GrantedAuthority> privileges = new ArrayList<GrantedAuthority>();
        for (GrantedAuthority role : authorities) {
            privileges.addAll(privilegesService.getPrivilegesForRole(role));
        }
        authorities.addAll(privileges);    
    }
}


public interface PrivilegesService {

     Collection<? extends GrantedAuthority> getPrivilegesForRole(GrantedAuthority role);
}


public class PropertyPrivilegesServiceImpl implements PrivilegesService {

    /**
     * Property bases mapping of roles to privileges.
     * Every role is one line, the privileges are comma separated.
     */
    private Properties roleToPrivileges;

    public PropertyPrivilegesServiceImpl(Properties roleToPrivileges) {
        if (roleToPrivileges == null) {
            throw new IllegalArgumentException("roleToPrivileges must not be null");
        }
        this.roleToPrivileges = roleToPrivileges;
    }

    @Override
    public Collection<? extends GrantedAuthority> getPrivilegesForRole(GrantedAuthority role) {
        if (roleToPrivileges == null) {
            throw new IllegalArgumentException("role must not be null");
        }

        String authority = role.getAuthority();
        if(authority != null) {
            String commaSeparatedPrivileges = roleToPrivileges.getProperty(role.getAuthority());
            if (commaSeparatedPrivileges != null) {
                List<GrantedAuthority> privileges = new ArrayList<GrantedAuthority>();
                for(String privilegeName : StringUtils.commaDelimitedListToSet(commaSeparatedPrivileges)) {
                    privileges.add(new GrantedAuthorityImpl(privilegeName.trim()));
                }                
                return privileges;
            } else {
                return Collections.emptyList();
            }
        } else {
            return Collections.emptyList();
        }
    }
}

配置示例

  <bean id="myUserDetailsService" class="JdbcDaoForUpdatableUsernames">
    <constructor-arg ref="propertyPrivilegesService"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="usersByUsernameQuery" value="SELECT login,encryptedPassword,loginEnabled FROM user WHERE login = ?"/>
    <property name="enableAuthorities" value="true"/>
    <property name="authoritiesByUsernameQuery" value="SELECT u.login, r.securityRoles FROM user u, user2security_roles r WHERE u.login= ? AND u.id = r. User_fk;"/>
</bean>

 <bean id="propertyPrivilegesService" class="PropertyPrivilegesServiceImpl">
    <constructor-arg>
        <props>
            <prop key="ROLE_ADMIN">
                ROLE_PREMIUM,
                ROLE_BASIC
            </prop>
            <prop key="ROLE_PREMIUM">
                RROLE_BASIC
            </prop>
        </props>
    </constructor-arg>
</bean>
 类似资料:
  • 我试图在我的Spring Boot应用程序中设置分层角色,但没有成功。我已经做了互联网上不同地方说过的所有事情。但是没有一个我能够解决这个问题。 这是我的SecurityConfig类的代码。当我用ROLE_ADMIN用户登录应用程序时,它应该能够从“/用户”检索数据,但目前我收到一个拒绝访问异常。如果用户有ROLE_USER凭据,它就可以正常工作。有人能帮我弄清楚是什么失败了吗?事先谢谢。 更新

  • 本文向大家介绍SpringSecurity 测试实战,包括了SpringSecurity 测试实战的使用技巧和注意事项,需要的朋友参考一下 引言 试题管理系统的安全模块使用Spring Security,代码从原华软仓库移植,在移植的过程中,发现原测试编写的不好,遂在新系统中对安全模块测试进行了重构。 Spring 测试 添加@SpringBootTest注解,意为这是一个基于SpringBoot

  • Docker 底层的核心技术包括 Linux 上的命名空间(Namespaces)、控制组(Control groups)、Union 文件系统(Union file systems)和容器格式(Container format)。 我们知道,传统的虚拟机通过在宿主主机中运行 hypervisor 来模拟一整套完整的硬件环境提供给虚拟机的操作系统。虚拟机系统看到的环境是可限制的,也是彼此隔离的。这

  • 1、基本架构 Docker 采用了 C/S架构,包括客户端和服务端。 Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。 Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。 Docker 客户端则为用户提供一系列可执行

  • 本节将对HubbleData的实验分层功能进行介绍。 1.1. 流量分配 A/B测试脱胎于药品测试的双盲实验,本身有非常严谨的科学依据。自从谷歌在互联网行业引入A/B测试以来,A/B测试已经成为互联网行业提升效率、优化运营的必备利器。随着A/B测试的普及,如何在科学性的前提下,尽可能降低成本成为我们研究的方向。 A/B测试最基本的原则是样本除了测试变量之外,其他特征必须完全一致,即所有用户仅受单一

  • 问题内容: 我知道使用这种方法来实现分页是一种不好的做法,因为当数据变大时,这会消耗大量内存。解决此问题的一种方法是按字段使用自然顺序: 问题是-我是mongo的新手,不知道什么是最好的方式 问题答案: 您正在谈论的概念可以称为“转发分页”。这有一个很好的理由,与使用和修饰符不同,它不能用于“返回”上一页或实际上“跳”至特定页面。至少不需要花费很多精力来存储“可见的”或“发现的”页面,因此,如果您