在 Spring Security 中实现分层角色 [英] Implementing Hierarchical Roles in Spring Security
问题描述
我正在尝试在 Spring 安全性中实现分层角色,并根据 spring 源文档在我的 xml 文件中添加了以下配置.
I am trying to implement Hierarchical roles in Spring security and added the following configuration in my xml files as per spring source documentation.
<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 站点中的那些行外,我什么也没找到.另外,如果您知道分层角色的任何良好实现,请务必提及它们.
I have tried with above lines but I am getting Access Denial while ROLE_ADMIN trying to access the url assigned to ROLE_BASIC. Do I need to add anything more than this. I found nothing other than those lines in Spring site. Also, If you know of any good implementation of Hierarchical roles, please do mention them.
推荐答案
我认为您需要在 accessDecisionManager
中注册 roleVoter
.@参见这个答案的例子.
I think you need to register the roleVoter
at the accessDecisionManager
.
@See this answer for an example.
但说实话,我怀疑 Spring Hierarchical Voter 概念,因为你需要在任何地方添加一个特殊的分层选民.我个人更喜欢另一种方式:我实现了一个自定义 JdbcDaoImpl
,它覆盖了 addCustomAuthorities
并将普通"角色添加到现有"角色一次.
But to be honest, I doubt the Spring Hierarchical Voter concept, because you need to add a special hierarchical voter everywhere. I personally prefer an other way: I have implemented an custom JdbcDaoImpl
that overrides the addCustomAuthorities
and add "normal" Roles to the "existing" once.
/**
* 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 Security 中实现分层角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!