2012-12-13 182 views
2

我試圖在使用Waffle NTML進行身份驗證時啓用Spring Security中的角色層次結構投票,但存在一些未知問題,因爲繼承角色不會像預期的那樣在主體上顯示爲阻止hasRole表達式攔截網址並使用授權的jsp taglibs。Spring Security角色層次結構問題

基於以下指導我一直在整合華夫:https://github.com/dblock/waffle/blob/master/Docs/spring/SpringSecuritySingleSignOnFilter.md

可正常工作自身使用標準的RoleVoter但問題在應用程序中開始,當我嘗試定製使用RoleHierarchyVoter我也測試了它自己(使用LDAP身份驗證提供程序)和角色層次結構完全按預期工作。

的合併華夫和RoleHierarchyVoter方法的配置如下:

華夫Specfic配置

<!-- 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的配置

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

設法解決我的這些問題歸咎於我的http命名空間公司的遺漏我從幾個小時的調試彈簧安全來源發現的配置。

問題是如何創建DefaultWebSecurityExpressionHandler。在剪斷它上面已經創造它作爲這個AccessDecisionManager的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> 

利用這種作用heirachies被用來確定處理定義爲截距的網址,如規則時訪問是否應當被准許:

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

但是,如果你想檢查使用JSP標籤庫授權如下(這是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)處理程序已定義。

因此,要解決我的問題,我創建了豆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> 

進行這些更改確保roleHeirarchies都考慮將通過http名稱空間定義爲攔截URL的Web安全表達式以及使用JSP Authorize taglib的表達式解釋爲這兩個表達式。