无法正确部署 Spring Security SAML 示例应用程序

Posted

技术标签:

【中文标题】无法正确部署 Spring Security SAML 示例应用程序【英文标题】:Cannot deploy Spring Security SAML sample application correctly 【发布时间】:2015-05-26 09:50:47 【问题描述】:

我正在尝试部署作为 Spring Security SAML 扩展一部分的示例应用程序,使用 SSOCircle 作为 IDP,但我遇到了许多问题。我真的很感激能帮我解决这个问题。

这就是我所做的。

我从:https://github.com/spring-projects/spring-security-saml/tree/1.0.0.RELEASE 下载了源代码,并通过:mvn package 构建了示例应用程序。然后我将 WAR 文件部署到独立的 Tomcat 实例 (v7.0.41)。

我启动了应用程序:http://server:8550/spring-security-saml2-sample, 点击元数据管理,然后点击登录按钮,但我一直被重定向回http://server:8550/spring-security-saml2-sample/saml/web/metadata/login。

我通过更改行绕过了元数据管理的登录:

<security:intercept-url pattern="/saml/web/**" access="ROLE_ADMIN"/>

在securityContext.xml 中:

<security:intercept-url pattern="/saml/web/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

导航回http://server:8550/spring-security-saml2-sample/saml/web/metadata,我现在可以单击生成新的服务提供商元数据按钮。我为 Entity ID 输入了一个值,接受了其余选项的默认值,然后单击了Generate metadata。 我按照说明将SP元数据文件保存到/WEB-INF/classes/metadata/serverId_sp.xml,并将SP配置数据添加到securityContext.xml中的metadata bean。 我登录https://idp.ssocircle.com/sso 并注册了SP 元数据。 然后我注释掉了这两条线:

<security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>

securityContext.xml,并重新启动应用程序。

在主页上,我选择了http://idp.ssocircle.com 选项,然后单击开始单点登录。我被正确重定向到 SSOCircle;我输入了我的用户名和密码,并被重定向回 spring-security-saml2-sample 应用程序,但显示以下错误:

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

关于这个具体问题,我认为这个答案 (Spring SAML integration with WSO2 Identity server, SAML Message ID not reconised) 不相关,因为我使用 SSOCircle 作为我的 IDP;即我的 SP 和 IDP 的域不同。

Spring SAML 文档中的 section on troubleshooting 提供了一种通过修改 securityContext.xml 中的 contextProvider bean 来禁用检查 InResponseToField 设置的方法。 我实施了这个修复,并再次重新启动了测试应用程序。

我可以像以前一样通过 SSOCircle 登录,但是现在当我被重定向回 spring-security-saml2-sample 时,我总是被重定向回http://server:8550/spring-security-saml2-sample/saml/discovery?entityID=serverId&returnIDParam=idp;即不显示登录用户的详细信息(如在线演示版http://saml-federation.appspot.com/),我从未看到全局注销本地注销按钮。即使我在浏览器中明确输入 URL http://server:8550/spring-security-saml2-sample,我总是会被重定向回 http://server:8550/spring-security-saml2-sample/saml/discovery?entityID=serverId&returnIDParam=idp。

由于我将示例应用程序部署到独立的 Tomcat 实例,因此我还进行了此答案中建议的更改:Spring Security SAML Metadata URL on Tomcat。但是,行为仍然相同。

所以,这就是我现在卡住的地方。任何想法可能导致我的问题?为什么我的示例应用程序版本与在线演示版本的行为方式不同?

我们将不胜感激地收到任何帮助 - 谢谢。

更新

网络流量的HAR文件在这里:http://pastebin.com/EUPHA4gE

到标准输出的调试输出很长;我把它分成两部分:

第一部分:http://pastebin.com/TkZS7uZM

第二部分:http://pastebin.com/mrRkLs2T

如果有帮助,我还发布了 Tomcat 访问日志:http://pastebin.com/992btULh

更新 2

更新后的网络流量的HAR文件在这里:http://pastebin.com/EUPHA4gE

我部署的原始 war 文件(在进行上述任何更改之前)在这里:https://dl.dropboxusercontent.com/u/18025575/spring-security-saml2-sample.war

如上所述,包含对各种文件的配置更改的 war 文件位于:https://dl.dropboxusercontent.com/u/18025575/spring-security-saml2-sample-with-changes.war

【问题讨论】:

您能记录下您的应用程序和 SSOCircle 之间的所有流量吗?理想情况下,按照此处toolbox.googleapps.com/apps/har_analyzer 的描述创建一个 HAR 文件,并将 HAR 作为链接添加到您的问题?另外,请按照docs.spring.io/autorepo/docs/spring-security-saml/… 中的说明启用调试日志记录并添加内容。 弗拉基米尔 - 非常感谢您的帮助。我已经创建了日志,并将输出添加到 pastebin。我已经添加了原始问题的链接。 艾伦,我一直在努力寻找问题所在,但到目前为止都失败了。您能否增强 har 文件,使其还包含对 Spring SAML 应用程序的第一个请求和 SSOCircle 的 SSO 登录?您能否上传您在某处部署的战争,以便我尝试重现它? 弗拉基米尔 - 再次感谢您一直以来的帮助;抱歉,我花了一段时间才回复。我更新了 HAR 文件输出,并上传了两个版本的 war 文件(配置更改之前和之后)。请参阅原始问题的链接。 谢谢,我会尽快过关的,但要出差一周,所以可能需要一段时间。 【参考方案1】:

您正在使用的示例,我也使用过相同的示例,并且可以正常工作。唯一的问题是您必须了解 Spring SAML 的工作原理。

它非常简单。 1. 将示例应用程序作为一个新项目部署到 tomcat 中。(不要进行任何更改)。

2.运行应用程序并使用路径 (/saml/metadata) 下载默认元数据。 前任。如果您的服务器是 localhost:8080/samlApplication 那么完整路径将是 localhost:8080/samlApplication/saml/metadata 注意: samlApplication 将是您的应用程序名称。

    将内容复制并替换为生成的元数据 XML 内容到 /WEB- INF/classes/metadata/serverId_sp.xml。

    转到 ssocircle 并注册元数据并确保您输入正确的实体 ID,它将在生成的元数据中,例如这个 entityID="your entitiy id"。使用相同的方法。

    现在运行应用程序并登录,您将被正确重定向到包含用户详细信息的主页。

您的问题出在元数据中。 IDP 使用 SP 元数据信息将用户重定向回 SP,因此如果您在重定向中遇到问题,那么 SP 元数据中肯定存在问题。

您能否发布您生成的元数据以便于检查。

这是我使用的演示应用程序。 按照上面的说明,试试你会成功的。 https://dl.dropboxusercontent.com/u/23694298/spring-saml-sso-sample.rar

【讨论】:

以上是关于无法正确部署 Spring Security SAML 示例应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 无法注销

即使凭据正确,Spring-security 也不会登录用户

Spring security - 身份验证在几天后停止工作 - 需要重新启动

Spring Security - 从 Tomcat 6 部署到 Tomcat 7 时凭据错误

无法在 Spring Security 中获取 @Secured Method Security 注释

iis部署sa登录失败