title: SAML remote Discovery service : missing "return" parameter
body: <p>I'm using Spring Security SAML 1.0.1. I've <a href="https://stackoverflow.com/questions/33741388/how-to-configure-the-remote-discovery-with-spring-security-saml">set up the IDP metadata so it reaches a Discovery service</a> which is defined by <code>idpDiscoveryURL</code>. This parameter contains the URL <code>http://wayf-shib.ueb.eu/fede-renater/WAYF</code>.</p>
  
  <p>The remote Discovery is reached, but it complains that the request does not contain the "return" parameter. Indeed, this is the request that Spring SAML generates:</p>
  
  <pre><code>http://wayf-shib.ueb.eu/fede-renater/WAYF?entityID=http%3A%2F%2Facem.u-bretagneloire.fr%3A80%2FACEM%2Fsaml%2Fmetadata&amp;returnIDParam=idp
  </code></pre>
  
  <p>The generated parameters are :</p>
  
  <ul>
  <li><code>entityID</code> with the correct value;</li>
  <li><code>returnIDParam</code> with the value "idp" that is set automatically by Spring SAML.</li>
  </ul>
  
  <p><strong>Question</strong> : How I can configure Spring Security SAML so that it generates a <code>return</code> parameter in the request?</p>
  
  <hr>
  
  <p>If this can help, this is my current configuration:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
  &lt;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"&gt;
  
  &lt;!-- Enable auto-wiring --&gt;
  &lt;context:annotation-config/&gt;
  
  &lt;!-- Scan for auto-wiring classes in spring saml packages --&gt;
  &lt;context:component-scan base-package="org.springframework.security.saml"/&gt;
  
  &lt;!-- Security for the administration UI --&gt;
  &lt;http pattern="/saml/web/**" use-expressions="false"&gt;
      &lt;access-denied-handler error-page="/saml/web/metadata/login"/&gt;
      &lt;form-login login-processing-url="/saml/web/login" login-page="/saml/web/metadata/login" default-target-url="/saml/web/metadata"/&gt;
      &lt;intercept-url pattern="/saml/web/metadata/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/&gt;
      &lt;intercept-url pattern="/saml/web/**" access="ROLE_ADMIN"/&gt;
      &lt;custom-filter before="FIRST" ref="metadataGeneratorFilter"/&gt;
  &lt;/http&gt;
  
  &lt;!-- Secured pages with SAML as entry point --&gt;
  &lt;http entry-point-ref="samlEntryPoint"  use-expressions="true" auto-config="true"&gt;
      &lt;!-- For Spring Security 4.x, we need to disable csrf, otherwise AJAX requests get 403:--&gt;
      &lt;csrf disabled="true"/&gt;
      &lt;intercept-url access="permitAll" pattern="/" /&gt;&lt;!-- To permit "/" allows the use of web.xml's &lt;welcome-file&gt; --&gt;
      &lt;intercept-url access="permitAll" pattern="/home" /&gt;
      &lt;intercept-url access="permitAll" pattern="/pages/exceptions/**" /&gt;
      &lt;intercept-url access="permitAll" pattern="/javax.faces.resource/**" /&gt;
      &lt;intercept-url access="permitAll" pattern="/resources/**" /&gt;
      &lt;intercept-url access="hasRole('ROLE_ADMIN')" pattern="/administration/**" /&gt;
      &lt;intercept-url access="hasRole('ROLE_ADMIN')" pattern="/rest/**" /&gt;
      &lt;intercept-url access="isAuthenticated()" pattern="/**"/&gt;&lt;!-- When the user is authentificated by the IDP, but doesn't exist in the application database --&gt;
      &lt;form-login login-page="/login" /&gt;
      &lt;logout logout-url="/logout" logout-success-url="/home"/&gt;
      &lt;custom-filter before="FIRST" ref="metadataGeneratorFilter"/&gt;
      &lt;custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/&gt;
  &lt;/http&gt;
  
  &lt;!-- Filters for processing of SAML messages --&gt;
  &lt;b:bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy"&gt;
      &lt;filter-chain-map request-matcher="ant"&gt;
          &lt;filter-chain pattern="/saml/login/**" filters="samlEntryPoint"/&gt;
          &lt;filter-chain pattern="/saml/logout/**" filters="samlLogoutFilter"/&gt;
          &lt;filter-chain pattern="/saml/metadata/**" filters="metadataDisplayFilter"/&gt;
          &lt;filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/&gt;
          &lt;filter-chain pattern="/saml/SSOHoK/**" filters="samlWebSSOHoKProcessingFilter"/&gt;
          &lt;filter-chain pattern="/saml/SingleLogout/**" filters="samlLogoutProcessingFilter"/&gt;
          &lt;filter-chain pattern="/saml/discovery/**" filters="samlIDPDiscovery"/&gt;
      &lt;/filter-chain-map&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Handler deciding where to redirect user after successful login --&gt;
  &lt;b:bean id="successRedirectHandler"
        class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"&gt;
      &lt;b:property name="defaultTargetUrl" value="/"/&gt;
      &lt;b:property name="alwaysUseDefaultTargetUrl" value="true"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Handler deciding where to redirect user after failed login --&gt;
  &lt;b:bean id="failureRedirectHandler"
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"&gt;
      &lt;b:property name="useForward" value="true"/&gt;
      &lt;b:property name="defaultFailureUrl" value="/error.jsp"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Handler for successful logout --&gt;
  &lt;b:bean id="successLogoutHandler" class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler"&gt;
      &lt;b:property name="defaultTargetUrl" value="/logout.jsp"/&gt;
  &lt;/b:bean&gt;
  
  &lt;authentication-manager alias="authenticationManager"&gt;
      &lt;!-- Register authentication manager for SAML provider --&gt;
      &lt;authentication-provider ref="samlAuthenticationProvider"/&gt;
      &lt;!-- Register authentication manager for administration UI --&gt;
      &lt;authentication-provider&gt;
          &lt;user-service id="adminInterfaceService"&gt;
              &lt;user name="admin" password="admin" authorities="ROLE_ADMIN"/&gt;
          &lt;/user-service&gt;
      &lt;/authentication-provider&gt;
  &lt;/authentication-manager&gt;
  
  &lt;!-- Logger for SAML messages and events --&gt;
  &lt;b:bean id="samlLogger" class="org.springframework.security.saml.log.SAMLDefaultLogger"/&gt;
  
  &lt;!-- Central storage of cryptographic keys --&gt;
  &lt;b:bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"&gt;
      &lt;b:constructor-arg value="classpath:security/samlKeystore.jks"/&gt;
      &lt;b:constructor-arg type="java.lang.String" value="nalle123"/&gt;
      &lt;b:constructor-arg&gt;
          &lt;b:map&gt;
              &lt;b:entry key="apollo" value="nalle123"/&gt;
          &lt;/b:map&gt;
      &lt;/b:constructor-arg&gt;
      &lt;b:constructor-arg type="java.lang.String" value="apollo"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Entry point to initialize authentication, default values taken from properties file --&gt;
  &lt;b:bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint"&gt;
      &lt;b:property name="defaultProfileOptions"&gt;
          &lt;b:bean class="org.springframework.security.saml.websso.WebSSOProfileOptions"&gt;
              &lt;b:property name="includeScoping" value="false"/&gt;
          &lt;/b:bean&gt;
      &lt;/b:property&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- IDP Discovery Service --&gt;
  &lt;b:bean id="samlIDPDiscovery" class="org.springframework.security.saml.SAMLDiscovery"&gt;
      &lt;b:property name="idpSelectionPath" value="/WEB-INF/security/idpSelection.jsp"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Filter automatically generates default SP metadata --&gt;
  &lt;b:bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter"&gt;
      &lt;b:constructor-arg&gt;
          &lt;b:bean class="org.springframework.security.saml.metadata.MetadataGenerator"&gt;
              &lt;b:property name="entityId" value="http://acem.u-bretagneloire.fr:80/ACEM"/&gt;
              &lt;b:property name="entityBaseURL" value="http://acem.u-bretagneloire.fr:80/ACEM"/&gt;
              &lt;!-- 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. --&gt;
              &lt;b:property name="nameID" value="PERSISTENT" /&gt;
              &lt;b:property name="includeDiscoveryExtension" value="true"/&gt;
              &lt;b:property name="extendedMetadata"&gt;
                  &lt;b:bean class="org.springframework.security.saml.metadata.ExtendedMetadata"&gt;
                      &lt;b:property name="idpDiscoveryEnabled" value="true"/&gt;
                      &lt;b:property name="idpDiscoveryURL" value="http://wayf-shib.ueb.eu/fede-renater/WAYF"/&gt;
                      &lt;b:property name="idpDiscoveryResponseURL" value="http://acem.u-bretagneloire.fr/ACEM/saml/login/alias/defaultAlias?disco=true&amp;amp;return=http%3A%2F%2acem.u-bretagneloire.fr/ACEM/"/&gt;
                  &lt;/b:bean&gt;
              &lt;/b:property&gt;
          &lt;/b:bean&gt;
      &lt;/b:constructor-arg&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- The filter is waiting for connections on URL suffixed with filterSuffix and presents SP metadata there --&gt;
  &lt;b:bean id="metadataDisplayFilter" class="org.springframework.security.saml.metadata.MetadataDisplayFilter"/&gt;
  
  &lt;!-- Configure HTTP Client to accept certificates from the keystore for HTTPS verification --&gt;
  &lt;!--
  &lt;b:bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolConfigurer"&gt;
      &lt;b:property name="sslHostnameVerification" value="default"/&gt;
  &lt;/b:bean&gt;
  --&gt;
  
  &lt;!-- IDP Metadata configuration - paths to metadata of IDPs in circle of 
      trust is here --&gt;
  &lt;b:bean id="metadata"
      class="org.springframework.security.saml.metadata.CachingMetadataManager"&gt;
      &lt;b:constructor-arg&gt;
          &lt;b:list&gt;
              &lt;b:bean
                  class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"&gt;
                  &lt;b:constructor-arg&gt;
                      &lt;b:bean
                          class="org.opensaml.saml2.metadata.provider.HTTPMetadataProvider"&gt;
                          &lt;!-- URL containing the metadata --&gt;
                          &lt;b:constructor-arg&gt;
                              &lt;b:value type="java.lang.String"&gt;https://federation.renater.fr/test/renater-test-metadata.xml&lt;/b:value&gt;
                          &lt;/b:constructor-arg&gt;
                          &lt;!-- Timeout for metadata loading in ms --&gt;
                          &lt;b:constructor-arg&gt;
                              &lt;b:value type="int"&gt;15000&lt;/b:value&gt;
                          &lt;/b:constructor-arg&gt;
                          &lt;b:property name="parserPool" ref="parserPool" /&gt;
                      &lt;/b:bean&gt;
                  &lt;/b:constructor-arg&gt;
                  &lt;b:constructor-arg&gt;
                      &lt;!-- Default extended metadata for entities not specified in the map --&gt;
                      &lt;b:bean
                          class="org.springframework.security.saml.metadata.ExtendedMetadata"&gt;
                          &lt;b:property name="idpDiscoveryEnabled" value="true"/&gt;
                          &lt;b:property name="idpDiscoveryURL" value="http://wayf-shib.ueb.eu/fede-renater/WAYF"/&gt;
                          &lt;b:property name="idpDiscoveryResponseURL" value="http://acem.u-bretagneloire.fr/ACEM/saml/login/alias/defaultAlias?disco=true&amp;amp;return=http%3A%2F%2acem.u-bretagneloire.fr/ACEM/"/&gt;
                      &lt;/b:bean&gt;
                  &lt;/b:constructor-arg&gt;
                  &lt;b:constructor-arg&gt;
                      &lt;!-- Extended metadata for specific IDPs --&gt;
                      &lt;b:map&gt;
                          &lt;b:entry key="http://idp.ssocircle.com"&gt;
                              &lt;b:bean
                                  class="org.springframework.security.saml.metadata.ExtendedMetadata" /&gt;
                          &lt;/b:entry&gt;
                      &lt;/b:map&gt;
                  &lt;/b:constructor-arg&gt;
              &lt;/b:bean&gt;
          &lt;/b:list&gt;
      &lt;/b:constructor-arg&gt;
      &lt;!-- OPTIONAL used when one of the metadata files contains information 
          about this service provider --&gt;
      &lt;b:property name="hostedSPName" value="http://acem.u-bretagneloire.fr:80/ACEM/saml/metadata"/&gt;
      &lt;!-- OPTIONAL property: can tell the system which IDP should be used for 
          authenticating user by default. --&gt;
      &lt;b:property name="defaultIDP" value="https://ident-shib-test.univ-rennes1.fr/idp/shibboleth"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- SAML Authentication Provider responsible for validating of received SAML messages --&gt;
  &lt;b:bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider"&gt;
      &lt;!-- OPTIONAL property: can be used to store/load user data after login --&gt;
      &lt;b:property name="userDetails"&gt;
          &lt;b:bean class="eu.ueb.acem.services.auth.SamlAuthenticationUserDetailsService"/&gt;
      &lt;/b:property&gt;
      &lt;!-- VERY IMPORTANT, OTHERWISE THE USER WILL BE REFERENCED BY THE NameID VALUE
           (example: _246558c0d7c514447292d750df577b6b) AND NOT THE USERDETAILS "LOGIN" VALUE --&gt;
      &lt;b:property name="forcePrincipalAsString" value="false"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Provider of default SAML Context --&gt;
  &lt;b:bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"/&gt;
  
  &lt;!-- Processing filter for WebSSO profile messages --&gt;
  &lt;b:bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter"&gt;
      &lt;b:property name="authenticationManager" ref="authenticationManager"/&gt;
      &lt;b:property name="authenticationSuccessHandler" ref="successRedirectHandler"/&gt;
      &lt;b:property name="authenticationFailureHandler" ref="failureRedirectHandler"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Processing filter for WebSSO Holder-of-Key profile --&gt;
  &lt;b:bean id="samlWebSSOHoKProcessingFilter" class="org.springframework.security.saml.SAMLWebSSOHoKProcessingFilter"&gt;
      &lt;b:property name="authenticationManager" ref="authenticationManager"/&gt;
      &lt;b:property name="authenticationSuccessHandler" ref="successRedirectHandler"/&gt;
      &lt;b:property name="authenticationFailureHandler" ref="failureRedirectHandler"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Logout handler terminating local session --&gt;
  &lt;b:bean id="logoutHandler"
        class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"&gt;
      &lt;b:property name="invalidateHttpSession" value="false"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Override default logout processing filter with the one processing SAML messages --&gt;
  &lt;b:bean id="samlLogoutFilter" class="org.springframework.security.saml.SAMLLogoutFilter"&gt;
      &lt;b:constructor-arg index="0" ref="successLogoutHandler"/&gt;
      &lt;b:constructor-arg index="1" ref="logoutHandler"/&gt;
      &lt;b:constructor-arg index="2" ref="logoutHandler"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Filter processing incoming logout messages --&gt;
  &lt;!-- First argument determines URL user will be redirected to after successful global logout --&gt;
  &lt;b:bean id="samlLogoutProcessingFilter" class="org.springframework.security.saml.SAMLLogoutProcessingFilter"&gt;
      &lt;b:constructor-arg index="0" ref="successLogoutHandler"/&gt;
      &lt;b:constructor-arg index="1" ref="logoutHandler"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Class loading incoming SAML messages from httpRequest stream --&gt;
  &lt;b:bean id="processor" class="org.springframework.security.saml.processor.SAMLProcessorImpl"&gt;
      &lt;b:constructor-arg&gt;
          &lt;b:list&gt;
              &lt;b:ref bean="redirectBinding"/&gt;
              &lt;b:ref bean="postBinding"/&gt;
              &lt;b:ref bean="artifactBinding"/&gt;
              &lt;b:ref bean="soapBinding"/&gt;
              &lt;b:ref bean="paosBinding"/&gt;
          &lt;/b:list&gt;
      &lt;/b:constructor-arg&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- SAML 2.0 WebSSO Assertion Consumer --&gt;
  &lt;b:bean id="webSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerImpl"/&gt;
  
  &lt;!-- SAML 2.0 Holder-of-Key WebSSO Assertion Consumer --&gt;
  &lt;b:bean id="hokWebSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/&gt;
  
  &lt;!-- SAML 2.0 Web SSO profile --&gt;
  &lt;b:bean id="webSSOprofile" class="org.springframework.security.saml.websso.WebSSOProfileImpl"/&gt;
  
  &lt;!-- SAML 2.0 Holder-of-Key Web SSO profile --&gt;
  &lt;b:bean id="hokWebSSOProfile" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/&gt;
  
  &lt;!-- SAML 2.0 ECP profile --&gt;
  &lt;b:bean id="ecpprofile" class="org.springframework.security.saml.websso.WebSSOProfileECPImpl"/&gt;
  
  &lt;!-- SAML 2.0 Logout Profile --&gt;
  &lt;b:bean id="logoutprofile" class="org.springframework.security.saml.websso.SingleLogoutProfileImpl"/&gt;
  
  &lt;!-- Bindings, encoders and decoders used for creating and parsing messages --&gt;
  &lt;b:bean id="postBinding" class="org.springframework.security.saml.processor.HTTPPostBinding"&gt;
      &lt;b:constructor-arg ref="parserPool"/&gt;
      &lt;b:constructor-arg ref="velocityEngine"/&gt;
  &lt;/b:bean&gt;
  
  &lt;b:bean id="redirectBinding" class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding"&gt;
      &lt;b:constructor-arg ref="parserPool"/&gt;
  &lt;/b:bean&gt;
  
  &lt;b:bean id="artifactBinding" class="org.springframework.security.saml.processor.HTTPArtifactBinding"&gt;
      &lt;b:constructor-arg ref="parserPool"/&gt;
      &lt;b:constructor-arg ref="velocityEngine"/&gt;
      &lt;b:constructor-arg&gt;
          &lt;b:bean class="org.springframework.security.saml.websso.ArtifactResolutionProfileImpl"&gt;
              &lt;b:constructor-arg&gt;
                  &lt;b:bean class="org.apache.commons.httpclient.HttpClient"&gt;
                      &lt;b:constructor-arg&gt;
                          &lt;b:bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/&gt;
                      &lt;/b:constructor-arg&gt;
                  &lt;/b:bean&gt;
              &lt;/b:constructor-arg&gt;
              &lt;b:property name="processor"&gt;
                  &lt;b:bean class="org.springframework.security.saml.processor.SAMLProcessorImpl"&gt;
                      &lt;b:constructor-arg ref="soapBinding"/&gt;
                  &lt;/b:bean&gt;
              &lt;/b:property&gt;
          &lt;/b:bean&gt;
      &lt;/b:constructor-arg&gt;
  &lt;/b:bean&gt;
  
  &lt;b:bean id="soapBinding" class="org.springframework.security.saml.processor.HTTPSOAP11Binding"&gt;
      &lt;b:constructor-arg ref="parserPool"/&gt;
  &lt;/b:bean&gt;
  
  &lt;b:bean id="paosBinding" class="org.springframework.security.saml.processor.HTTPPAOS11Binding"&gt;
      &lt;b:constructor-arg ref="parserPool"/&gt;
  &lt;/b:bean&gt;
  
  &lt;!-- Initialization of OpenSAML library--&gt;
  &lt;b:bean class="org.springframework.security.saml.SAMLBootstrap"/&gt;
  
  &lt;!-- Initialization of the velocity engine --&gt;
  &lt;b:bean id="velocityEngine" class="org.springframework.security.saml.util.VelocityFactory" factory-method="getEngine"/&gt;
  
  &lt;!-- XML parser pool needed for OpenSAML parsing --&gt;
  &lt;b:bean id="parserPool" class="org.opensaml.xml.parse.StaticBasicParserPool" init-method="initialize"&gt;
      &lt;b:property name="builderFeatures"&gt;
          &lt;b:map&gt;
              &lt;b:entry key="http://apache.org/xml/features/dom/defer-node-expansion" value="false"/&gt;
          &lt;/b:map&gt;
      &lt;/b:property&gt;
  &lt;/b:bean&gt;
  
  &lt;b:bean id="parserPoolHolder" class="org.springframework.security.saml.parser.ParserPoolHolder"/&gt;
  </code></pre>
  
  <p></p>