Announcement Announcement Module
Collapse
No announcement yet.
SAML Integration Problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • SAML Integration Problem

    I am developing an SSO solution using the Spring Security-SAML implementation. I am having difficulties integrating an existing IdP with Spring Security on the source side acting as the SP.

    Upon access of a protected resource on the source side, I am successfully able to connect to the IdP with an AuthnRequest. The IdP presents the user with a login, authenticates the user, and transmits an AuthnResponse to the SP. However, the Spring Security SAML implementation has trouble digesting the response. The error I receive is as follows:

    Code:
    org.opensaml.common.SAMLRuntimeException: Error deconding incoming SAML message
        org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:64)
        org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:258)
        org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        org.springframework.security.saml.metadata.MetadataDisplayFilter.doFilterHttp(MetadataDisplayFilter.java:90)
        org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        org.springframework.security.saml.SAMLEntryPoint.doFilterHttp(SAMLEntryPoint.java:104)
        org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
        org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
        org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
        org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
        org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    Unfortunately, the Spring Security-SAML code is swallowing the original exception, so I do not have a further stack trace to aid in troubleshooting. I can only assume that the digital signature used to sign the response from the IdP does not match what the SP expects, but I am having difficulties validating that this is the problem.

    Does anyone have any insight on what configuration parameters I should check? The certificates on both the IdP and SP appear to match.

  • #2
    Hi Steve. (That is you, right? )

    I recommend turning up the logging on org.opensaml.* and org.apache.xml, as those are the underlying libs that will do the decode/signature check. If it's getting that far, it should tell you something interesting.

    Also, check the version of the saml-spring extension you are using. You error message does not match what's in git. The newer version wraps the underlying exception, so whatever is catching it (your container?) can unwrap it and show you the cause.

    Finally, if that does not help you, you can always download spring-saml and use the jcox.spring.SSOResponseIntTest. By plugging in an actual SAMLResponse you capture from Live HTTP Headers you can see how open saml will decode and do the signature check of the message. But that would require setting up that project and subbing in your keystore, so it might be overkill for what you're trying to solve here. It also may be something with how the saml security extension is using saml-meta, so running the integration test will not help you diagnose the problem (other than prove that it is a valid saml message with a valid signature).


    -Jim

    Comment


    • #3
      Jim, how are you? Hopefully, TPS is treating you well.

      I began taking the steps below after I posted this message. You're right, I was using the original version of Spring Security-SAML which completely swallowed the original exceptions. Since I had the source, I modified the code to provide a bit more extensive debugging and was able to get to the root cause.

      The root cause is not an easy one to fix. It is not a problem with Spring Security-SAML, but a symptom of the OpenSAML 2.2 libraries used for SAML decoding. It turns out we have some hardware here that does SSL translation before it sends the request on to the configured service provider. Since the original request URL no longer matches the endpoint after this translation, OpenSAML throws an exception indicating the intended destination and recipient endpoint don't match.

      From the research I've done, it appears to be a fairly common gripe with OpenSAML. There are numerous ways of getting around this, from hardware configuration to intercepting the HTTP Request in the Spring SAML code to even writing your own OpenSAML implementation. At this point, it's just a matter of picking which poison is the least painful to our existing configuration.

      Comment


      • #4
        Yeah, I've seen something like this before. We had a service provider that was forwarded to by mod_proxy; same result. To be fair, the Open SAML guys are just following the spec.

        It's not that hard to get Open SAML to 'play ball,' You just need to extend their HTTPPostDecoder (assuming that is the binding) and override
        Code:
        protected String getActualReceiverEndpointURI(
        			SAMLMessageContext messageContext) throws MessageDecodingException { ...}
        to either fake the URI check, or replace httpRequest.getRequestURL() with the expected value. In the case of mod_proxy, we compared it to the X-Forwarded-Host header. I don't know how easy it would be to plug your own decoder into the Spring Security SAML extension, but I'm sure it's doable.

        Good luck,
        Jim

        Comment


        • #5
          To get me past the proof-of-concept, I modified the OpenSAML library locally to not throw an exception on the URL condition. To wit, I ran across two places in the Spring SAML code that performs the same exact verification; those, too had to be bypassed.

          The only other problem I ran into was with the AuthnResponse from the IdP not being signed. In looking at the metadata generated from the Spring SAML SP, the option is explicitly set to require assertions to be signed. I realize I am still on the original 1.0-SNAPSHOT code and I don't know the standard very well, but is there a way to configure this parameter? Since the WebSSOProfile gets an SP configuration from OpenSAML based on specified role (and doesn't explicitly set the parameter), I can only assume it's part of the spec. Since my IdP currently is not signing assertions, I've had to code around this for now.

          Aside from the aforementioned issues, my implementation is up and running.

          Comment

          Working...
          X