Announcement Announcement Module
Collapse
No announcement yet.
InResponseToField doesn't correspond to sent message Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • InResponseToField doesn't correspond to sent message

    I am using POST binding for SSO with AD FS. My SP sends an AuthNRequest and AD FS presents a login screen. I receive a good Assertion with status success. The debug log next shows AuthNResponse FAILURE due to "InResponseToField doesn't correspond to sent message."

    From the debug log, the value of InResponseTo on the Assertion does match the ID in the AuthNRequest. Therefore, I do not understand why I am getting this error.

    I appreciate any ideas on what is going on with this.

    Thanks,
    Mark

  • #2
    Are you by any chance setting property storageFactory on the SAMLContextProvierImpl or do you include some SAMLMessageStorageFactory implementation as a bean in your config?

    SAML Extension stores the sent request in the message storage and retrieves it during processing of the response. It can fail with the error you see in case the request cannot be found in the storage. This could be caused either by some issue with HTTP sessions (where the request is stored) or by using a different implementation (e.g. EmptyStorageFactory).

    Cheers, Vladi

    Comment


    • #3
      My app is a simple test app with a securityContext.xml close to the sample app. I am not using storageFactory or doing anything with the message store that I am aware of.

      As a test, I changed WebSSOProfileConsumerImpl.java as follows to not retrieve the message from the message store, since that call returns null:

      log.debug("getInResponseTo returned " + response.getInResponseTo());
      log.debug("length is " + response.getInResponseTo().length());

      // Verify response to field if present, set request if correct
      SAMLMessageStorage messageStorage = context.getMessageStorage();

      //if (messageStorage != null && response.getInResponseTo() != null) {
      // XMLObject xmlObject = messageStorage.retrieveMessage(response.getInRespo nseTo());
      // if (xmlObject == null) {
      // log.debug("InResponseToField doesn't correspond to sent message", response.getInResponseTo());
      // ...
      //}

      SSO between my app and AD FS works with the above block commented out. The InResponseTo value is good. Of course, this doesn't resolve my problem but may be some useful information.

      You said there could be an issue with HTTP sessions. I am not doing anything with sessions explicitly. What should I look at if this is the problem?

      Thanks,
      Mark

      Comment


      • #4
        Hi Mark,

        This is very peculiar. You should be able to work-around the issue by setting property storageFactory on SAMLContextProviderImpl with bean EmptyStorageFactory. This disables verification of inResponseTo field without any code changes. It's secure with Artifact binding. With other bindings it could possibly allow replay attacks.

        But I'd really like to figure out where the problem is. Could you please make few modifications and let me know what the result of the outputs is?

        Change class WebSSOProfileImpl (line 111) to:

        Code:
        SAMLMessageStorage messageStorage = context.getMessageStorage();
        if (messageStorage != null) {
            messageStorage.storeMessage(authRequest.getID(), authRequest);
            HttpSessionStorage store = (HttpSessionStorage) messageStorage;
            System.out.println(Arrays.toString(store.getAllMessages().toArray()));
            System.out.println(((HttpServletRequestAdapter)context.getInboundMessageTransport()).getWrappedRequest().getSession(false).getId());
        }
        Change class WebSSOProfileConsumerImpl (line 127) to:

        Code:
        // Verify response to field if present, set request if correct
        SAMLMessageStorage messageStorage = context.getMessageStorage();
        HttpSessionStorage store = (HttpSessionStorage) messageStorage;
        System.out.println(Arrays.toString(store.getAllMessages().toArray()));
        System.out.println(((HttpServletRequestAdapter)context.getInboundMessageTransport()).getWrappedRequest().getSession(false).getId());
        Cheers, Vladi

        Comment


        • #5
          Hi Vladi,

          I will add:

          <bean id="contextProvider" class="org.springframework.security.saml.context.S AMLContextProviderImpl">
          <property name="storageFactory" value="org.springframework.security.saml.storage.E mptyStorageFactory"/>
          </bean>

          and run the test without my previous code change.

          I will then remove the above xml and run the test with your changes to WebSSOProfileImpl and WebSSOProfileConsumerImpl.
          I expect to post results Monday.

          Thanks,
          Mark

          Comment


          • #6
            Hi Vladi,

            As you said, with the bean definition for SAMLContextProviderImpl referencing EmptyStorageFactory, my test app works.

            With EmptyStorageFactory removed it fails with the InReponseTo problem. The output from your changes is:

            [a1j8g2e64dhhc66fj2aj4bge930ah]
            91CE1C6DBAF0DBA524E430C8813C0115
            []
            E3A05499601838113D410DE55F629AD0

            Something that might be the cause of this is that after setting up the Relying Party trust, the configuration was changed on the AD FS side to use POST binding instead of Artifact binding. I did not change the SP metadata, I only added:

            <property name="assertionConsumerIndex" value="1"/>

            to securityContext.xml. Is that invalid and I should regenerate the metadata (I use your sample app) either by setting SSO HTTP-POST binding as the default or by unchecking SSO Artifact binding?

            Regards,
            Mark

            Comment


            • #7
              I had the same issue, and I traced it back to the fact that the samlEntryPoint was being triggered on a request for an HTTPS resource, while the IDP was redirecting back to an HTTP endpoint. A different session object gets created for HTTP as opposed to HTTPS, since the JSESSIONID cookie will not be served up by the browser when the protocol and port are different. The fix for me was to ensure that my SP meta-data has the AssertionConsumerService bound to an HTTPS location. Not sure if you have the same symptoms, but it is useful to know that this can occur when the default HttpSessionStorageFactory is being used.
              Last edited by cdevoto; Mar 18th, 2013, 03:06 PM.

              Comment


              • #8
                When I generate the SP metadata for POST binding only and take out the assertionConsumerIndex value="1" and the EmptyStorageFactory bean, SSO works fine.

                Mark

                Comment


                • #9
                  Glad you got it resolved!

                  The change of assertionConsumerIndex alone doesn't explain the alteration of HttpSessionID between request and response. But the cause is very likely what cdevoto had described (and thanks for that, I wasn't aware of this particular issue).

                  In the future I'll add (or perhaps a contributor could add?) another SAMLMessageStorage implementation which a) stores sent messages globally outside of the HTTP Session and b) replicates data cluster-wide. This would make this issue go away.

                  Vladimir

                  Comment


                  • #10
                    The InResponseTo problem resurfaced but so did a reason. The problem occurs if I enter http://localhost/myapp on the browser. If I invoke using my hostname, which is in the AD FS relying party trust endpoint, it works ok.

                    Mark

                    Comment


                    • #11
                      This explains everything - system creates the first HttpSession tracked with a cookie on the localhost domain (this one contains the sent request), then it creates another on the hostname (which doesn't contain the original request and therefore fails during verification). A cluster-wide SAMLMessageStorage mentioned earlier would then certainly cover this situation.

                      Vladi

                      Comment


                      • #12
                        Hi Vladimir,

                        Could you please explain and give me advice in the same issue like this

                        Originally posted by vsch View Post
                        system creates the first HttpSession tracked with a cookie on the localhost domain (this one contains the sent request), then it creates another on the hostname (which doesn't contain the original request and therefore fails during verification).
                        SP sends url without port but IDp answer url with port. That is why I receive message "InResponseToField doesn't correspond to sent message."

                        I can not understand how SAMLMessageStorage can solve this problem. For example I added my application-сontext-security.txt file. Could you show how it solve in configuration file with more details?
                        Last edited by postullat; Aug 13th, 2013, 02:55 PM.

                        Comment


                        • #13
                          Hi,

                          The requirement for this to work is simple - the HttpSession available to the user when sending the SAML request must be the same as the HttpSession available when receiving the SAML response.

                          The SAMLMessageStorage is used to store sent SAML requests (e.g. for verification of the InResponseTo field). And the default implementation is using HttpSession. This implies the requirement above.

                          Using the EmptyStorageFactory bean effectively disables checking of the InResponseTo field and can be thus be used as a workaround (with some security implications).

                          The fact that IDP responds with URL which includes the port doesn't necessarily need to be a problem - as long as the request was sent from http://host/app/... and the response is coming to http://host:80/app/..., or request was sent from https://... and response coming https://app:443/...

                          Is your application available on both HTTP and HTTPS ports? If so you should make sure that the entityBaseURL property is correctly set on the MetadataGenerator bean (otherwise your SP metadata with be generated with either http or https based on the first request coming to the server). And then make sure that SAML SSO is initialized from the same scheme.

                          To troubleshoot this you can also use network inspector in your browser and make sure that the session cookie (e.g. JSESSION) has the same value when the request is sent and when the response is received in your SP.

                          Vladi

                          Comment


                          • #14
                            Originally posted by vsch View Post
                            The SAMLMessageStorage is used to store sent SAML requests (e.g. for verification of the InResponseTo field). And the default implementation is using HttpSession. This implies the requirement above.

                            Using the EmptyStorageFactory bean effectively disables checking of the InResponseTo field and can be thus be used as a workaround.
                            Regarding implementation case above.
                            Will be correct if I just add the EmptyStorageFactory and SAMLMessageStorage beans in my application-сontext-security file:

                            <bean id="samlMessageStorage " class="org.springframework.security ... SAMLMessageStorage "/>
                            <bean id="emptyStorageFactory " class="org.springframework.security ... EmptyStorageFactory "/>

                            or maybe it must be instead of another beans?

                            Originally posted by vsch View Post
                            ... with some security implications).
                            What are security implications possible and How can I avoid this? Maybe there are other ways to solve issue related with InResponseToField error message?

                            Originally posted by vsch View Post
                            Is your application available on both HTTP and HTTPS ports? If so you should make sure that the entityBaseURL property is correctly set on the MetadataGenerator bean (otherwise your SP metadata with be generated with either http or https based on the first request coming to the server). And then make sure that SAML SSO is initialized from the same scheme.
                            Yes, our application supports https. This information is very helpfull for me. I will check application configuration tomorrow. Thank you very much.

                            Regards,
                            Volodymyr

                            Comment


                            • #15
                              Hi Vladi,

                              Any update regarding question above?

                              Also I have additional questions regarding https.
                              Case of using http. When my app sends request with http and after that it receives response with http url and they match.
                              But when I want to switch protocol to https the app doesn't work. I tried set entityBaseURL in the MetadataGenerator bean, one of example is:

                              <!-- Filter automatically generates default SP metadata -->
                              <bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata. MetadataGeneratorFilter">
                              <constructor-arg>
                              <bean class="org.springframework.security.saml.metadata. MetadataGenerator">
                              <property name="bindingsSSO"><list><value>POST</value></list></property>
                              <property name="bindingsSLO"><list><value>Redirect</value><value>POST</value></list></property>
                              <property name="bindingsHoKSSO"><list/></property>
                              <property name="includeDiscovery" value="false"/>
                              <property name="keyManager" ref="keyManager"/>
                              <property name="entityId" value="${saml-sp-name-id}"/>
                              <property name="entityBaseURL" value="https://10.25.11.139/crs"/>

                              </bean>
                              </constructor-arg>
                              <property name="normalizeBaseUrl" value="true"></property>
                              </bean>

                              but it also doesn't work.
                              What I do wrong?

                              Comment

                              Working...
                              X