2015-11-26 55 views
0

我正在使用Spring Security SAML 1.0.1。我有set up the IDP metadata so it reaches a Discovery service,它由idpDiscoveryURL定義。該參數包含URL http://wayf-shib.ueb.eu/fede-renater/WAYFSAML遠程發現服務:缺少「返回」參數

已到達遠程發現,但它抱怨該請求不包含「返回」參數。事實上,這是Spring SAML生成請求:

http://wayf-shib.ueb.eu/fede-renater/WAYF?entityID=http%3A%2F%2Facem.u-bretagneloire.fr%3A80%2FACEM%2Fsaml%2Fmetadata&returnIDParam=idp 

所生成的參數是:

  • entityID與正確值;
  • returnIDParam由值爲「idp」的值由Spring SAML自動設置。

問題:如何配置Spring Security SAML,使其產生的請求return參數?


如果這能幫助,這是我目前的配置:

<?xml version="1.0" encoding="UTF-8" ?> 
<b:beans xmlns:b="http://www.springframework.org/schema/beans" 
    xmlns="http://www.springframework.org/schema/security" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd 
      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd 
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

<!-- Enable auto-wiring --> 
<context:annotation-config/> 

<!-- Scan for auto-wiring classes in spring saml packages --> 
<context:component-scan base-package="org.springframework.security.saml"/> 

<!-- Security for the administration UI --> 
<http pattern="/saml/web/**" use-expressions="false"> 
    <access-denied-handler error-page="/saml/web/metadata/login"/> 
    <form-login login-processing-url="/saml/web/login" login-page="/saml/web/metadata/login" default-target-url="/saml/web/metadata"/> 
    <intercept-url pattern="/saml/web/metadata/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
    <intercept-url pattern="/saml/web/**" access="ROLE_ADMIN"/> 
    <custom-filter before="FIRST" ref="metadataGeneratorFilter"/> 
</http> 

<!-- Secured pages with SAML as entry point --> 
<http entry-point-ref="samlEntryPoint" use-expressions="true" auto-config="true"> 
    <!-- For Spring Security 4.x, we need to disable csrf, otherwise AJAX requests get 403:--> 
    <csrf disabled="true"/> 
    <intercept-url access="permitAll" pattern="/" /><!-- To permit "/" allows the use of web.xml's <welcome-file> --> 
    <intercept-url access="permitAll" pattern="/home" /> 
    <intercept-url access="permitAll" pattern="/pages/exceptions/**" /> 
    <intercept-url access="permitAll" pattern="/javax.faces.resource/**" /> 
    <intercept-url access="permitAll" pattern="/resources/**" /> 
    <intercept-url access="hasRole('ROLE_ADMIN')" pattern="/administration/**" /> 
    <intercept-url access="hasRole('ROLE_ADMIN')" pattern="/rest/**" /> 
    <intercept-url access="isAuthenticated()" pattern="/**"/><!-- When the user is authentificated by the IDP, but doesn't exist in the application database --> 
    <form-login login-page="/login" /> 
    <logout logout-url="/logout" logout-success-url="/home"/> 
    <custom-filter before="FIRST" ref="metadataGeneratorFilter"/> 
    <custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/> 
</http> 

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

<!-- Handler deciding where to redirect user after successful login --> 
<b:bean id="successRedirectHandler" 
     class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> 
    <b:property name="defaultTargetUrl" value="/"/> 
    <b:property name="alwaysUseDefaultTargetUrl" value="true"/> 
</b:bean> 

<!-- Handler deciding where to redirect user after failed login --> 
<b:bean id="failureRedirectHandler" 
     class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 
    <b:property name="useForward" value="true"/> 
    <b:property name="defaultFailureUrl" value="/error.jsp"/> 
</b:bean> 

<!-- Handler for successful logout --> 
<b:bean id="successLogoutHandler" class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler"> 
    <b:property name="defaultTargetUrl" value="/logout.jsp"/> 
</b:bean> 

<authentication-manager alias="authenticationManager"> 
    <!-- Register authentication manager for SAML provider --> 
    <authentication-provider ref="samlAuthenticationProvider"/> 
    <!-- Register authentication manager for administration UI --> 
    <authentication-provider> 
     <user-service id="adminInterfaceService"> 
      <user name="admin" password="admin" authorities="ROLE_ADMIN"/> 
     </user-service> 
    </authentication-provider> 
</authentication-manager> 

<!-- Logger for SAML messages and events --> 
<b:bean id="samlLogger" class="org.springframework.security.saml.log.SAMLDefaultLogger"/> 

<!-- Central storage of cryptographic keys --> 
<b:bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"> 
    <b:constructor-arg value="classpath:security/samlKeystore.jks"/> 
    <b:constructor-arg type="java.lang.String" value="nalle123"/> 
    <b:constructor-arg> 
     <b:map> 
      <b:entry key="apollo" value="nalle123"/> 
     </b:map> 
    </b:constructor-arg> 
    <b:constructor-arg type="java.lang.String" value="apollo"/> 
</b:bean> 

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

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

<!-- Filter automatically generates default SP metadata --> 
<b:bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter"> 
    <b:constructor-arg> 
     <b:bean class="org.springframework.security.saml.metadata.MetadataGenerator"> 
      <b:property name="entityId" value="http://acem.u-bretagneloire.fr:80/ACEM"/> 
      <b:property name="entityBaseURL" value="http://acem.u-bretagneloire.fr:80/ACEM"/> 
      <!-- POSSIBLY IMPORTANT, OTHERWISE THE USER MIGHT BE REFERENCED BY THE NameID VALUE 
       (example: _246558c0d7c514447292d750df577b6b) AND NOT THE USERDETAILS "LOGIN" VALUE 
       Note : I haven't tested to remove this property and see if it still works. --> 
      <b:property name="nameID" value="PERSISTENT" /> 
      <b:property name="includeDiscoveryExtension" value="true"/> 
      <b:property name="extendedMetadata"> 
       <b:bean class="org.springframework.security.saml.metadata.ExtendedMetadata"> 
        <b:property name="idpDiscoveryEnabled" value="true"/> 
        <b:property name="idpDiscoveryURL" value="http://wayf-shib.ueb.eu/fede-renater/WAYF"/> 
        <b:property name="idpDiscoveryResponseURL" value="http://acem.u-bretagneloire.fr/ACEM/saml/login/alias/defaultAlias?disco=true&amp;return=http%3A%2F%2acem.u-bretagneloire.fr/ACEM/"/> 
       </b:bean> 
      </b:property> 
     </b:bean> 
    </b:constructor-arg> 
</b:bean> 

<!-- The filter is waiting for connections on URL suffixed with filterSuffix and presents SP metadata there --> 
<b:bean id="metadataDisplayFilter" class="org.springframework.security.saml.metadata.MetadataDisplayFilter"/> 

<!-- Configure HTTP Client to accept certificates from the keystore for HTTPS verification --> 
<!-- 
<b:bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer"> 
    <b:property name="sslHostnameVerification" value="default"/> 
</b:bean> 
--> 

<!-- IDP Metadata configuration - paths to metadata of IDPs in circle of 
    trust is here --> 
<b:bean id="metadata" 
    class="org.springframework.security.saml.metadata.CachingMetadataManager"> 
    <b:constructor-arg> 
     <b:list> 
      <b:bean 
       class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"> 
       <b:constructor-arg> 
        <b:bean 
         class="org.opensaml.saml2.metadata.provider.HTTPMetadataProvider"> 
         <!-- URL containing the metadata --> 
         <b:constructor-arg> 
          <b:value type="java.lang.String">https://federation.renater.fr/test/renater-test-metadata.xml</b:value> 
         </b:constructor-arg> 
         <!-- Timeout for metadata loading in ms --> 
         <b:constructor-arg> 
          <b:value type="int">15000</b:value> 
         </b:constructor-arg> 
         <b:property name="parserPool" ref="parserPool" /> 
        </b:bean> 
       </b:constructor-arg> 
       <b:constructor-arg> 
        <!-- Default extended metadata for entities not specified in the map --> 
        <b:bean 
         class="org.springframework.security.saml.metadata.ExtendedMetadata"> 
         <b:property name="idpDiscoveryEnabled" value="true"/> 
         <b:property name="idpDiscoveryURL" value="http://wayf-shib.ueb.eu/fede-renater/WAYF"/> 
         <b:property name="idpDiscoveryResponseURL" value="http://acem.u-bretagneloire.fr/ACEM/saml/login/alias/defaultAlias?disco=true&amp;return=http%3A%2F%2acem.u-bretagneloire.fr/ACEM/"/> 
        </b:bean> 
       </b:constructor-arg> 
       <b:constructor-arg> 
        <!-- Extended metadata for specific IDPs --> 
        <b:map> 
         <b:entry key="http://idp.ssocircle.com"> 
          <b:bean 
           class="org.springframework.security.saml.metadata.ExtendedMetadata" /> 
         </b:entry> 
        </b:map> 
       </b:constructor-arg> 
      </b:bean> 
     </b:list> 
    </b:constructor-arg> 
    <!-- OPTIONAL used when one of the metadata files contains information 
     about this service provider --> 
    <b:property name="hostedSPName" value="http://acem.u-bretagneloire.fr:80/ACEM/saml/metadata"/> 
    <!-- OPTIONAL property: can tell the system which IDP should be used for 
     authenticating user by default. --> 
    <b:property name="defaultIDP" value="https://ident-shib-test.univ-rennes1.fr/idp/shibboleth"/> 
</b:bean> 

<!-- SAML Authentication Provider responsible for validating of received SAML messages --> 
<b:bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider"> 
    <!-- OPTIONAL property: can be used to store/load user data after login --> 
    <b:property name="userDetails"> 
     <b:bean class="eu.ueb.acem.services.auth.SamlAuthenticationUserDetailsService"/> 
    </b:property> 
    <!-- VERY IMPORTANT, OTHERWISE THE USER WILL BE REFERENCED BY THE NameID VALUE 
     (example: _246558c0d7c514447292d750df577b6b) AND NOT THE USERDETAILS "LOGIN" VALUE --> 
    <b:property name="forcePrincipalAsString" value="false"/> 
</b:bean> 

<!-- Provider of default SAML Context --> 
<b:bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"/> 

<!-- Processing filter for WebSSO profile messages --> 
<b:bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter"> 
    <b:property name="authenticationManager" ref="authenticationManager"/> 
    <b:property name="authenticationSuccessHandler" ref="successRedirectHandler"/> 
    <b:property name="authenticationFailureHandler" ref="failureRedirectHandler"/> 
</b:bean> 

<!-- Processing filter for WebSSO Holder-of-Key profile --> 
<b:bean id="samlWebSSOHoKProcessingFilter" class="org.springframework.security.saml.SAMLWebSSOHoKProcessingFilter"> 
    <b:property name="authenticationManager" ref="authenticationManager"/> 
    <b:property name="authenticationSuccessHandler" ref="successRedirectHandler"/> 
    <b:property name="authenticationFailureHandler" ref="failureRedirectHandler"/> 
</b:bean> 

<!-- Logout handler terminating local session --> 
<b:bean id="logoutHandler" 
     class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"> 
    <b:property name="invalidateHttpSession" value="false"/> 
</b:bean> 

<!-- Override default logout processing filter with the one processing SAML messages --> 
<b:bean id="samlLogoutFilter" class="org.springframework.security.saml.SAMLLogoutFilter"> 
    <b:constructor-arg index="0" ref="successLogoutHandler"/> 
    <b:constructor-arg index="1" ref="logoutHandler"/> 
    <b:constructor-arg index="2" ref="logoutHandler"/> 
</b:bean> 

<!-- Filter processing incoming logout messages --> 
<!-- First argument determines URL user will be redirected to after successful global logout --> 
<b:bean id="samlLogoutProcessingFilter" class="org.springframework.security.saml.SAMLLogoutProcessingFilter"> 
    <b:constructor-arg index="0" ref="successLogoutHandler"/> 
    <b:constructor-arg index="1" ref="logoutHandler"/> 
</b:bean> 

<!-- Class loading incoming SAML messages from httpRequest stream --> 
<b:bean id="processor" class="org.springframework.security.saml.processor.SAMLProcessorImpl"> 
    <b:constructor-arg> 
     <b:list> 
      <b:ref bean="redirectBinding"/> 
      <b:ref bean="postBinding"/> 
      <b:ref bean="artifactBinding"/> 
      <b:ref bean="soapBinding"/> 
      <b:ref bean="paosBinding"/> 
     </b:list> 
    </b:constructor-arg> 
</b:bean> 

<!-- SAML 2.0 WebSSO Assertion Consumer --> 
<b:bean id="webSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerImpl"/> 

<!-- SAML 2.0 Holder-of-Key WebSSO Assertion Consumer --> 
<b:bean id="hokWebSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/> 

<!-- SAML 2.0 Web SSO profile --> 
<b:bean id="webSSOprofile" class="org.springframework.security.saml.websso.WebSSOProfileImpl"/> 

<!-- SAML 2.0 Holder-of-Key Web SSO profile --> 
<b:bean id="hokWebSSOProfile" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/> 

<!-- SAML 2.0 ECP profile --> 
<b:bean id="ecpprofile" class="org.springframework.security.saml.websso.WebSSOProfileECPImpl"/> 

<!-- SAML 2.0 Logout Profile --> 
<b:bean id="logoutprofile" class="org.springframework.security.saml.websso.SingleLogoutProfileImpl"/> 

<!-- Bindings, encoders and decoders used for creating and parsing messages --> 
<b:bean id="postBinding" class="org.springframework.security.saml.processor.HTTPPostBinding"> 
    <b:constructor-arg ref="parserPool"/> 
    <b:constructor-arg ref="velocityEngine"/> 
</b:bean> 

<b:bean id="redirectBinding" class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding"> 
    <b:constructor-arg ref="parserPool"/> 
</b:bean> 

<b:bean id="artifactBinding" class="org.springframework.security.saml.processor.HTTPArtifactBinding"> 
    <b:constructor-arg ref="parserPool"/> 
    <b:constructor-arg ref="velocityEngine"/> 
    <b:constructor-arg> 
     <b:bean class="org.springframework.security.saml.websso.ArtifactResolutionProfileImpl"> 
      <b:constructor-arg> 
       <b:bean class="org.apache.commons.httpclient.HttpClient"> 
        <b:constructor-arg> 
         <b:bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/> 
        </b:constructor-arg> 
       </b:bean> 
      </b:constructor-arg> 
      <b:property name="processor"> 
       <b:bean class="org.springframework.security.saml.processor.SAMLProcessorImpl"> 
        <b:constructor-arg ref="soapBinding"/> 
       </b:bean> 
      </b:property> 
     </b:bean> 
    </b:constructor-arg> 
</b:bean> 

<b:bean id="soapBinding" class="org.springframework.security.saml.processor.HTTPSOAP11Binding"> 
    <b:constructor-arg ref="parserPool"/> 
</b:bean> 

<b:bean id="paosBinding" class="org.springframework.security.saml.processor.HTTPPAOS11Binding"> 
    <b:constructor-arg ref="parserPool"/> 
</b:bean> 

<!-- Initialization of OpenSAML library--> 
<b:bean class="org.springframework.security.saml.SAMLBootstrap"/> 

<!-- Initialization of the velocity engine --> 
<b:bean id="velocityEngine" class="org.springframework.security.saml.util.VelocityFactory" factory-method="getEngine"/> 

<!-- XML parser pool needed for OpenSAML parsing --> 
<b:bean id="parserPool" class="org.opensaml.xml.parse.StaticBasicParserPool" init-method="initialize"> 
    <b:property name="builderFeatures"> 
     <b:map> 
      <b:entry key="http://apache.org/xml/features/dom/defer-node-expansion" value="false"/> 
     </b:map> 
    </b:property> 
</b:bean> 

<b:bean id="parserPoolHolder" class="org.springframework.security.saml.parser.ParserPoolHolder"/> 

回答

0

解決它!參數return必須使用編碼形式的查詢字符串idpDiscoveryURL來傳遞。

雖然這聽起來很明顯,但當我們閱讀文檔時(根本沒有關於此參數的所有內容),這實際上並非如此。

因爲Spring SAML的大部分配置都是使用<property name="..." value="..." />標籤完成的,所以我花了兩週的時間正確配置這些東西。

我的豆metadata的配置現在看起來是這樣的:

<!-- IDP Metadata configuration - paths to metadata of IDPs in circle of 
    trust is here --> 
<b:bean id="metadata" 
    class="org.springframework.security.saml.metadata.CachingMetadataManager"> 
    <b:constructor-arg> 
     <b:list> 
      <b:bean 
       class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"> 
       <b:constructor-arg> 
        <b:bean 
         class="org.opensaml.saml2.metadata.provider.HTTPMetadataProvider"> 
         <!-- URL containing the metadata --> 
         <b:constructor-arg> 
          <b:value type="java.lang.String">https://federation.renater.fr/test/renater-test-metadata.xml</b:value> 
         </b:constructor-arg> 
         <!-- Timeout for metadata loading in ms --> 
         <b:constructor-arg> 
          <b:value type="int">15000</b:value> 
         </b:constructor-arg> 
         <b:property name="parserPool" ref="parserPool" /> 
        </b:bean> 
       </b:constructor-arg> 
       <b:constructor-arg> 
        <!-- Default extended metadata for entities not specified in the map --> 
        <b:bean 
         class="org.springframework.security.saml.metadata.ExtendedMetadata"> 
         <b:property name="idpDiscoveryEnabled" value="true"/> 
         <b:property name="idpDiscoveryURL" value="https://wayf-test.ueb.eu/fede-renater-ueb-test/WAYF?return=http%3A%2F%2Facem.u-bretagneloire.fr%2FACEM%2Fsaml%2Flogin"/> 
         <!-- 
         <b:property name="idpDiscoveryURL" value="https://discovery.renater.fr/test?entityId=http%3A%2F%2Facem.u-bretagneloire.fr%3A80%2FACEM%2Fsaml%2Fmetadata&amp;return=http%3A%2F%2Facem.u-bretagneloire.fr%2FACEM%2Fsaml%2Flogin"/> 
         --> 
         <b:property name="idpDiscoveryResponseURL" value="http://acem.u-bretagneloire.fr/ACEM/saml/login/alias/defaultAlias?disco=true"/> 
        </b:bean> 
       </b:constructor-arg> 
       <b:constructor-arg> 
        <!-- Extended metadata for specific IDPs --> 
        <b:map> 
         <b:entry key="http://idp.ssocircle.com"> 
          <b:bean 
           class="org.springframework.security.saml.metadata.ExtendedMetadata" /> 
         </b:entry> 
        </b:map> 
       </b:constructor-arg> 
      </b:bean> 
     </b:list> 
    </b:constructor-arg> 
    <!-- OPTIONAL used when one of the metadata files contains information 
     about this service provider --> 
    <b:property name="hostedSPName" value="http://acem.u-bretagneloire.fr:80/ACEM/saml/metadata"/> 
    <!-- OPTIONAL property: can tell the system which IDP should be used for 
     authenticating user by default. --> 
    <b:property name="defaultIDP" value="https://ident-shib-test.univ-rennes1.fr/idp/shibboleth"/> 
</b:bean>