I'm trying to deploy the sample application that's part of the Spring Security SAML extension, using SSOCircle as the IDP, but I've run into a number of problems. I'd really appreciate some help fixing this.
Here's what I've done.
I downloaded the source from: https://github.com/spring-projects/spring-security-saml/tree/1.0.0.RELEASE and built the sample application via : mvn package
. I then deployed the WAR file to a standalone instance of Tomcat (v7.0.41).
I launched the app: http://server:8550/spring-security-saml2-sample, clicked on Metadata Administration, and clicked on the Login button, but I kept being redirecting back to http://server:8550/spring-security-saml2-sample/saml/web/metadata/login.
I bypassed login for Metadata Administration by changing the line:
<security:intercept-url pattern="/saml/web/**" access="ROLE_ADMIN"/>
in securityContext.xml to:
<security:intercept-url pattern="/saml/web/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
Navigating back to http://server:8550/spring-security-saml2-sample/saml/web/metadata, I could now click on the Generate new service provider metadata button. I entered a value for Entity ID, accepted defaults for the remaining options, and clicked Generate metadata.
I saved the SP metadata file to /WEB-INF/classes/metadata/serverId_sp.xml
as instructed, and added the SP configuration data to metadata
bean in securityContext.xml
.
I logged in to https://idp.ssocircle.com/sso and registered SP metadata.
I then commented out both occurrences of the line:
<security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
in securityContext.xml
, and restarted the application.
On the main page I selected the http://idp.ssocircle.com option, and clicked Start single sign-on. I was correctly redirected to SSOCircle; I entered my user name & password, and was redirected back to the spring-security-saml2-sample application, but the following error was displayed:
org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:95)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:84)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message a2ei6e3068d8fi72g4a0fcc1j41142
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:139)
at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:82)
... 29 more
Regarding this specific problem, I don't think this answer (Spring SAML integration with WSO2 Identity server, SAML Message ID not reconised) is relevant, since I'm using SSOCircle as my IDP; i.e. the domains for my SP and the IDP are different.
The section on troubleshooting in the Spring SAML documentation gives a way to disable checking the InResponseToField
setting by modifying the contextProvider
bean in securityContext.xml
.
I implemented this fix, and restarted the test application once more.
I can log in via SSOCircle as before, but now when I'm redirected back to spring-security-saml2-sample, I'm always redirected back to http://server:8550/spring-security-saml2-sample/saml/discovery?entityID=serverId&returnIDParam=idp; i.e. the details of the logged in user are not displayed (as in the online demo version at http://saml-federation.appspot.com/), and I never see the Global Logout and Local Logout buttons. Even if I enter the URL http://server:8550/spring-security-saml2-sample explicitly in my browser, I'm always redirected back to http://server:8550/spring-security-saml2-sample/saml/discovery?entityID=serverId&returnIDParam=idp.
Since I'm deploying the sample application to a standalone instance of Tomcat, I also made the changes suggested in this answer: Spring Security SAML Metadata URL on Tomcat. However, the behaviour is still the same.
So, this is where I'm stuck now. Any ideas what might be causing my problems? Why isn't my version of the sample application behaving the same way as the online demo version?
Any help will be gratefully received - thank you.
UPDATE
The HAR file of the network traffic is here: http://pastebin.com/EUPHA4gE
The debug output to stdout is quite long; I've split it into two parts:
Part one: http://pastebin.com/TkZS7uZM
Part two: http://pastebin.com/mrRkLs2T
I've also posted the Tomcat access log if that's a help: http://pastebin.com/992btULh
UPDATE 2
The HAR file of the updated network traffic is here: http://pastebin.com/EUPHA4gE
The original war file I deployed (before making any of the changes mentioned above) is here: https://dl.dropboxusercontent.com/u/18025575/spring-security-saml2-sample.war
A war file containing the configuration changes to various files, as described above, is here: https://dl.dropboxusercontent.com/u/18025575/spring-security-saml2-sample-with-changes.war