2014-03-24 95 views
8

我試圖在Spring安全中實現分層角色,並根據Spring源文檔在我的xml文件中添加了以下配置。在Spring Security中實現分層角色

<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站點中的這些行之外,我什麼都沒發現。另外,如果您知道任何分層角色的良好實施,請務必提及它們。

回答

3

我想你需要註冊roleVoteraccessDecisionManager。 @查看this answer舉例。


但說實話,我doubt the Spring Hierarchical Voter concept,因爲你需要到處添加一個特殊的階層選民。我個人比較喜歡其他方式:我實現了一個自定義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> 
+0

@carlspring:沒有可用的公共示例。 (所有你需要在這個答案中實現這個)。 - 名稱:我將其命名爲「角色特權方法」,但這不是正式名稱。 – Ralph

3

嘗試通過添加這彈簧的security.xml

<http auto-config="true" use-expressions="true" access-decision-manager-ref="accessDecisionManager"> 


<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> 
    <beans:constructor-arg> 
     <beans:list> 
      <beans:ref bean="roleVoter" /> 
     </beans:list> 
    </beans:constructor-arg> 
</beans:bean> 
相關問題