2014-03-24 7 views
8

Ich versuche, Hierarchical-Rollen in Spring-Sicherheit zu implementieren, und fügte die folgende Konfiguration in meinen XML-Dateien wie Quell Quelldokumentation hinzu.Hierarchische Rollen im Frühjahr implementieren Sicherheit

<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> 

Ich habe mit obigen Zeilen versucht, aber ich bin immer Zugang Denial während ROLE_ADMIN die URL ROLE_BASIC zugewiesen zuzugreifen versuchen. Muss ich etwas mehr hinzufügen? Ich habe nichts anderes gefunden als diese Zeilen im Spring-Site. Wenn Sie eine gute Implementierung hierarchischer Rollen kennen, erwähnen Sie sie bitte.

Antwort

3

Ich denke, Sie müssen die roleVoter unter der accessDecisionManager registrieren. @Siehe this answer für ein Beispiel.


Aber um ehrlich zu sein, ich doubt the Spring Hierarchical Voter concept, weil man überall einen speziellen hierarchischen Wähler hinzufügen muß. Ich persönlich bevorzuge einen anderen Weg: Ich habe eine benutzerdefinierte JdbcDaoImpl implementiert, die die addCustomAuthorities überschreibt und "normale" Rollen zum "vorhandenen" einmal hinzufügt.

/** 
* 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(); 
     } 
    } 
} 

Beispiel Config

<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: Es gibt kein öffentliches Beispiel zur Verfügung. (alles, was Sie brauchen, um dies in dieser Antwort zu implementieren). - Name: Ich nenne es "Rollen-Privileg-Ansatz", aber das ist kein offizieller Name. – Ralph

3

Versuche durch das Hinzufügen dieser zu feder 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>