복붙노트

[SPRING] 스프링 보안 역할 계층 구조 문제

SPRING

스프링 보안 역할 계층 구조 문제

Waffle NTML을 사용하여 인증 할 때 상속 된 역할이 예상대로 주체에 대한 권한으로 나타나지 않는 스프링 보안에서 역할 계층 구조 투표를 사용하려고합니다. intercept urls와 authorize jsp taglibs에서 hasRole 표현식을 방지합니다. .

다음 가이드를 기반으로 와플을 통합했습니다. https://github.com/dblock/waffle/blob/master/Docs/spring/SpringSecuritySingleSignOnFilter.md

이것은 표준 RoleVoter를 사용하여 응용 프로그램 내에서 예상대로 작동하지만 나도 (LDAP 인증 공급자를 사용하여) 자체적으로 테스트 한 RoleHierarchyVoter를 사용하도록 사용자 정의하려고하면 문제가 시작되고 역할 계층 구조는 다음과 같이 정확하게 작동합니다. 예상했다.

Waffle과 RoleHierarchyVoter를 결합한 접근 방식의 설정은 다음과 같습니다.

와플 전용 구성

<!-- windows authentication provider -->
<bean id="waffleWindowsAuthProvider" class="waffle.windows.auth.impl.WindowsAuthProviderImpl" />

<!-- collection of security filters -->
<bean id="negotiateSecurityFilterProvider" class="waffle.servlet.spi.NegotiateSecurityFilterProvider">
    <constructor-arg ref="waffleWindowsAuthProvider" />
</bean>

<bean id="basicSecurityFilterProvider" class="waffle.servlet.spi.BasicSecurityFilterProvider">
    <constructor-arg ref="waffleWindowsAuthProvider" />
</bean>

<bean id="waffleSecurityFilterProviderCollection" class="waffle.servlet.spi.SecurityFilterProviderCollection">
    <constructor-arg>
        <list>
            <ref bean="negotiateSecurityFilterProvider" />              
            <ref bean="basicSecurityFilterProvider" />              
        </list>
    </constructor-arg>
</bean>

<bean id="negotiateSecurityFilterEntryPoint" class="waffle.spring.NegotiateSecurityFilterEntryPoint">
    <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
</bean>

<!-- spring security filter -->
<bean id="waffleNegotiateSecurityFilter" class="waffle.spring.NegotiateSecurityFilter">
    <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
    <property name="AllowGuestLogin" value="false" />
    <property name="PrincipalFormat" value="fqn" />
    <property name="RoleFormat" value="fqn" />
    <property name="GrantedAuthorityFactory" ref="simpleGrantedAuthorityFactory" />
    <!-- set the default granted authority to null as we don't need to assign a default role of ROLE_USER -->
    <property name="defaultGrantedAuthority"><null/></property>

</bean>

<!-- custom granted authority factory so the roles created are based on the name rather than the fqn-->
<bean id="simpleGrantedAuthorityFactory" class="xx.yy.zz.SimpleGrantedAuthorityFactory">
    <constructor-arg name="prefix" value="ROLE_"/>
    <constructor-arg name="convertToUpperCase" value="true"/>
</bean>

익숙한 스프링 보안 구성

<!-- declare the entry point ref as the waffle defined entry point -->
<sec:http use-expressions="true"
          disable-url-rewriting="true"
          access-decision-manager-ref="accessDecisionManager"
          entry-point-ref="negotiateSecurityFilterEntryPoint" >

    <sec:intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>

    .
    . access denied handlers, concurrency control, port mappings etc
    .

    <sec:custom-filter ref="waffleNegotiateSecurityFilter" position="BASIC_AUTH_FILTER" />

</sec:http>

<!-- spring authentication provider -->
<sec:authentication-manager alias="authenticationProvider" />


<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="decisionVoters">
        <list>
            <ref bean="roleHierarchyVoter" />
            <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                <property name="expressionHandler">
                    <bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
                        <property name="roleHierarchy" ref="roleHierarchy"/>
                    </bean>
                </property>
            </bean>
        </list>
    </property>
</bean>

<bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_TEST_1 > ROLE_TEST_2
            ROLE_TEST_2 > ROLE_TEST_3
            ROLE_TEST_3 > ROLE_TEST_4
        </value>
    </property>
</bean>

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

해결법

  1. ==============================

    1.스프링 보안 소스를 몇 시간 동안 디버깅 해본 결과 내 http 네임 스페이스 구성에서 누락 된 문제점을 해결했습니다.

    스프링 보안 소스를 몇 시간 동안 디버깅 해본 결과 내 http 네임 스페이스 구성에서 누락 된 문제점을 해결했습니다.

    문제는 DefaultWebSecurityExpressionHandler가 어떻게 생성되었는지입니다. 위에 짤린다면 accessDecisionManager의 bean 정의 안에 내부 bean으로 그것을 만들었습니다 :

    <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
        <property name="expressionHandler">
            <bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
                <property name="roleHierarchy" ref="roleHierarchy"/>
            </bean>
        </property> 
    </bean>
    

    이 역할 계층 구조는 다음과 같이 절편 URL로 정의 된 규칙을 처리 할 때 액세스 권한을 부여해야하는지 여부를 결정하는 데 사용됩니다.

    <sec:intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
    

    그러나 아래의 JSP Authorize taglib을 사용하여 권한 부여를 확인하고자하는 경우 (이것은 프리 마커에 있음) 역할에 영향을 미치지 않습니다. Heechrechies는 고려하지 않습니다.

    <@security.authorize access="hasRole('ROLE_TEST_1)">
        <p>You have role 1</p>
    </@security.authorize>
    
    <@security.authorize access="hasRole('ROLE_TEST_4')">
        <p>You have role 4</p>
    </@security.authorize>
    

    이는 내부 bean으로 작성된 DefaultWebSecurityExpressionHandler가 액세스 결정 관리자 내에서만 사용되지만 taglib 표현식의 경우 security http namespace expression-handler가 정의되지 않은 한 새로운 기본 bean이 작성됩니다 (RoleHierarchy를 사용하지 않음).

    그래서, 내 문제를 해결하기 위해 DefaultWebSecurityExpressionHandler 빈을 생성하고이를 내 WebExpressionVoter 빈 정의 내에서 참조하고 다음과 같이 표현 핸들러로 사용했습니다.

    <sec:http ... >
    
        .
        . access denied handlers, concurrency control, port mappings etc
        .
    
        <sec:expression-handler ref="defaultWebSecurityExpressionHandler" />
    
    </sec:http>
    
    <bean id="defaultWebSecurityExpressionHandler"
          class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
          <property name="roleHierarchy" ref="roleHierarchy"/>
    </bean>
    
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <ref bean="roleHierarchyVoter" />
                <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                    <property name="expressionHandler" ref="defaultWebSecurityExpressionHandler"/>
                </bean>
            </list>
        </property>
    </bean>
    

    이러한 변경을 수행하면 http 네임 스페이스를 통한 인터셉트 URL로 정의 된 Web Security Expressions와 JSP Authorize taglib을 사용하는 표현식 둘 다에 대해 역할이 고려됩니다.

  2. from https://stackoverflow.com/questions/13860705/spring-security-role-hierarchy-issues by cc-by-sa and MIT license