복붙노트

[SPRING] 스프링 보안에서 계층 적 역할 구현하기

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

    1.accessDecisionManager에 roleVoter를 등록해야한다고 생각합니다. @ 예를 들어이 대답을보십시오.

    accessDecisionManager에 roleVoter를 등록해야한다고 생각합니다. @ 예를 들어이 대답을보십시오.

    그러나 솔직히 말해서 나는 모든 계층의 특별한 유권자를 추가해야하기 때문에 Spring Hierarchical Voter 개념을 의심합니다. 필자는 개인적으로 다른 방법을 선호합니다. addCustomAuthorities를 재정의하고 "기존"역할에 "일반"역할을 한 번 추가하는 사용자 정의 JdbcDaoImpl을 구현했습니다.

    /**
     * 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>
    
  2. ==============================

    2.이것을 spring-security.xml에 추가하여보십시오 :

    이것을 spring-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>
    
  3. from https://stackoverflow.com/questions/22611029/implementing-hierarchical-roles-in-spring-security by cc-by-sa and MIT license