2013-06-14 33 views
7

私はSpring SecurityとSAMLに関する問題を解明しようとしています。私たちは、Spring Security(spring-security-core-3.1.1.RELEASE.jar)とSAML(spring-security-saml2-core-1.0.0-RC1-SNAPSHOT.jar)を使用して、 SAML SP。編集:ここに私のセキュリティ関連のコンテキストXMLの(私は思う!)関連セクションです。ご覧のとおり、this sample XMLとほぼ同じです。SpringセキュリティとネストされたFilterChainProxy SAMLサービスプロバイダの作成

<!-- Entry point to initialize authentication, default values taken from properties file --> 
<bean id="samlEntryPoint" class="com.myproduct.samlsp.impl.PSSAMLEntryPoint"> 
    <property name="defaultProfileOptions"> 
     <bean class="org.springframework.security.saml.websso.WebSSOProfileOptions"> 
      <property name="includeScoping" value="false"/> 
     </bean> 
    </property> 
</bean> 

<!-- Unsecured pages --> 
<security:http security="none" pattern="/saml/web/**"/> 
<security:http security="none" pattern="/logout.jsp"/> 
<security:http security="none" pattern="/favicon.ico"/> 
<security:http security="none" pattern="/images/**"/> 
<security:http security="none" pattern="/scripts/**"/> 
<security:http security="none" pattern="/flash/**"/> 
<security:http security="none" pattern="/loggedout.html"/> 

<!-- Secured pages --> 
<security:http entry-point-ref="samlEntryPoint"> 
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/> 
    <security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/> 
    <security:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/> 
</security:http> 

<!-- IDP Discovery Service --> 
<bean id="samlIDPDiscovery" class="org.springframework.security.saml.SAMLDiscovery"> 
    <property name="idpSelectionPath" value="/WEB-INF/security/idpSelection.jsp"/> 
</bean> 

<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy"> 
    <security:filter-chain-map request-matcher="ant"> 
     <security:filter-chain pattern="/saml/login/**" filters="samlEntryPoint"/> 
     <security:filter-chain pattern="/saml/logout/**" filters="samlLogoutFilter"/> 
     <security:filter-chain pattern="/saml/metadata/**" filters="metadataDisplayFilter"/> 
     <security:filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/> 
     <security:filter-chain pattern="/saml/SSOHoK/**" filters="samlWebSSOHoKProcessingFilter"/> 
     <security:filter-chain pattern="/saml/SingleLogout/**" filters="samlLogoutProcessingFilter"/> 
     <security:filter-chain pattern="/saml/discovery/**" filters="samlIDPDiscovery"/> 
    </security:filter-chain-map> 
</bean> 

症状は、IDPによる認証直後に、私のSPのページが正しく表示されます。ただし、URLを変更すると(リンクをクリックするなど)、すぐにIDPに送り返されます。なぜか分かったと思うが、どうしてこれがいつも正しいとは限らないのか分からない。

私がSpring Securityを理解したことは、認可チェックがすべてSecurityContextHolderに基づいていることです。つまり、認証オブジェクトをホルダーに置くと、すべてが認証チェックを行います。次に、SecurityContextPersistenceFilterは、セッションリポジトリを一致させるように管理します。

私は春のセキュリティコードをトレースように、私は次のコードでSecurityContextPersistenceFilterを参照してください。

SecurityContext contextBeforeChainExecution = repo.loadContext(holder); 
try { 
    SecurityContextHolder.setContext(contextBeforeChainExecution); 
    chain.doFilter(holder.getRequest(), holder.getResponse()); 
} finally { 
    SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext(); 
    // Crucial removal of SecurityContextHolder contents - do this before anything else. 
    SecurityContextHolder.clearContext(); 
    repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); 
    .... 
} 

これまでのところ、とても良いです。次に、私はFilterChainProxyを見て、見つけます:

これはまだOKです。 FilterChainProxyはすべてのSpring Securityフィルタのベースで一度だけ呼び出される必要があるため、その時点でSecurityContextHolderをクリアすることは問題にはなりません。

ただし、これは起こっていません。実際に起こっているのは、FilterControlのclearContextが呼び出されてからSecurityContextPersistenceFilterがcontextAfterChainExecutionにコンテキストからそれを読み取る機会を得ることです。これが起こっている理由は、実際にFilterChainProxyがコールチェーンで2回発生するためです。私はFilterChainProxy.doFilterにブレークポイントを設定し、それが2度呼び出されているのでこれを知っています。最初に呼び出されると、そのFilterChainにFilterChainProxyの別のインスタンスがあります。フィルタのこのチェーンで

org[email protected]78104d3c 
org.springframework.security.[email protected] 
FilterChainProxy[ Filter Chains: [ .... my patterns ] ], 
org.sp[email protected]7fffde92 
org.springframework.[email protected]e2d09d7 
org.springfram[email protected]1c2b968f 
o[email protected]395f222a 
org[email protected]372e6f09 
org.springfr[email protected]7dab91aa 

、私はSecurityContextPersistenceFilterが今まで働くことができる方法を理解していない:ここでFilterChainProxyのgetFiltersメソッドによって返されるフィルタのスタックがあり、それは機会を得る前にSecurityContextHolderは常にクリアされますように思えますそれを維持する。

ここに明らかな問題がありますか?

答えて

4

私はこれについて明確な説明を得ることはできませんでしたが、Spring Security 3.1.1がSpring SAMLや実際に実装されていないことが原因です同じ種類の入れ子になったFilterChainProxysを使用します。 FilterChainProxyは3.1.1で完全に書き直されたようです。最新のリリース(3.1.4)を見ると、SecurityContextHolder( "SEC-1950")がフィルタの最初の呼び出しである場合にのみ、finally節にチェックがあることに気付きました。

したがって、バネのセキュリティを3.1.4にアップグレードすることで問題は解決しました。

+0

解決策を投稿していただきありがとうございます。あなたのソリューションが私のために働いたのと同じ問題に直面していました。 –

+0

聞いてうれしい私はそれを見た唯一の人ではない。フォローアップありがとう! – fool4jesus

+0

私は春のセキュリティバージョンを3.1.4.RELEASEにアップグレードした後も同じ問題に直面しています。 – ManojP

関連する問題