2

Waffle NTML を使用して認証するときに Spring Security でロール階層の投票を有効にしようとしていますが、継承されたロールが期待どおりにプリンシパルの権限として表示されないという未知の問題があり、インターセプト URL の両方で hasRole 式が防止され、authorize jsp taglibs が使用されます。 .

次のガイドに基づいてワッフルを統合しています: 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>

おなじみのSpring Security Config

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

1 に答える 1

4

Spring セキュリティ ソースを何時間もデバッグして見つけた、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 (これは freemarker にあります) を使用して承認を確認したい場合は、roleHeirachies が考慮されないため機能しません。

<@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 式の場合、セキュリティ http 名前空間式ハンドラーが定義されていない限り、新しいデフォルト Bean が作成されます (RoleHierarchy を使用しません)。

したがって、私の問題を解決するために、Bean DefaultWebSecurityExpressionHandler を作成し、それを WebExpressionVoter Bean 定義内で参照し、次のように式ハンドラーとしても使用しました。

<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 セキュリティ式と、JSP Authorize taglib を使用する式の両方で roleHeirarchies が確実に考慮されます。

于 2012-12-14T11:32:20.680 に答える