SAMLException:响应的 InResponseToField 与发送的消息不对应
SAMLException: InResponseToField of the Response doesn't correspond to sent message
我们正在开发一个受 spring 安全 saml 保护的应用程序。
认证正常,但在生产环境中出现以下工作流程问题
- 用户请求未受保护的地址www.server.com
- 响应是一个带有内联脚本的 html 页面,该脚本将 window.location.href 更改为受 saml 保护的页面(服务提供商)www.server.com/app/action?param1=value1¶m2=值 2
- spring saml 检测到需要身份验证并将用户重定向到 www.login-server.com
上的登录表单(身份提供者)
- 此时登录表单是显示给用户的第一个页面
- 用户将此登录页面添加为书签(包括此 http 会话的 saml 相关 url 参数)www.login-server.com/adfs/ls/?SAMLRequest=xxx&SigAlg=xxx&Signature=arGdsZwJtHzTDjQP1oYqbjNO
- 用户使用应用程序...
- 第二天用户打开此书签并登录
- IdP 重定向到 SP 但所属的 http 会话已经过期
现在我们的应用程序出现以下异常:
org.opensaml.common.SAMLException:响应的 InResponseToField 与发送的消息 arGdsZwJtHzTDjQP1oYqbjNO
不对应
关于如何处理此工作流以便用户在成功登录后可以使用该应用程序有什么想法吗?
感谢您的回答!
当您申请生成一个 AuthnRequest 时,该请求有一个您的应用程序以某种方式保留的 ID。来自 IdP 的相应响应必须将 InResponseTo 属性设置为相同的 ID 值,以便您的应用程序可以验证该响应是否针对它发送的请求。
但是,当您的用户将包含请求 (www.login-server.com/adfs/ls/?SAMLRequest=xxx...) 的 adfs link 添加为书签时,您的应用程序完全忘记了关于那个请求。换句话说,它不再将请求 ID 保存在某处并且无法验证响应。
解决方案是告诉您的用户不要为www.login-服务器添加书签。com/adfs/ls/?SAMLRequest=xxx...link.相反,他们必须在您的应用程序中为 link 添加书签,它可以在其中生成新请求并发送到 ADFS。
我们通过对 spring saml 配置进行以下更改解决了我们的问题:
- 在 ID 为
successRedirectHandler
(org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
) 的 bean 中,我们将 defaultTargetUrl 设置为我们应用程序的 init-Action(包括所有请求参数)。此 url 将在 IdP 启动 SSO 的情况下自动使用。
- 在 ID 为
contextProvider
(org.springframework.security.saml.context.SAMLContextProviderLB
) 的 Bean 中,我们将 storageFactory 设置为 org.springframework.security.saml.storage.EmptyStorageFactory
。这将禁用对 InResponseToField 的检查。
我们正在开发一个受 spring 安全 saml 保护的应用程序。
认证正常,但在生产环境中出现以下工作流程问题
- 用户请求未受保护的地址www.server.com
- 响应是一个带有内联脚本的 html 页面,该脚本将 window.location.href 更改为受 saml 保护的页面(服务提供商)www.server.com/app/action?param1=value1¶m2=值 2
- spring saml 检测到需要身份验证并将用户重定向到 www.login-server.com 上的登录表单(身份提供者)
- 此时登录表单是显示给用户的第一个页面
- 用户将此登录页面添加为书签(包括此 http 会话的 saml 相关 url 参数)www.login-server.com/adfs/ls/?SAMLRequest=xxx&SigAlg=xxx&Signature=arGdsZwJtHzTDjQP1oYqbjNO
- 用户使用应用程序...
- 第二天用户打开此书签并登录
- IdP 重定向到 SP 但所属的 http 会话已经过期
现在我们的应用程序出现以下异常:
org.opensaml.common.SAMLException:响应的 InResponseToField 与发送的消息 arGdsZwJtHzTDjQP1oYqbjNO
不对应关于如何处理此工作流以便用户在成功登录后可以使用该应用程序有什么想法吗? 感谢您的回答!
当您申请生成一个 AuthnRequest 时,该请求有一个您的应用程序以某种方式保留的 ID。来自 IdP 的相应响应必须将 InResponseTo 属性设置为相同的 ID 值,以便您的应用程序可以验证该响应是否针对它发送的请求。
但是,当您的用户将包含请求 (www.login-server.com/adfs/ls/?SAMLRequest=xxx...) 的 adfs link 添加为书签时,您的应用程序完全忘记了关于那个请求。换句话说,它不再将请求 ID 保存在某处并且无法验证响应。
解决方案是告诉您的用户不要为www.login-服务器添加书签。com/adfs/ls/?SAMLRequest=xxx...link.相反,他们必须在您的应用程序中为 link 添加书签,它可以在其中生成新请求并发送到 ADFS。
我们通过对 spring saml 配置进行以下更改解决了我们的问题:
- 在 ID 为
successRedirectHandler
(org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
) 的 bean 中,我们将 defaultTargetUrl 设置为我们应用程序的 init-Action(包括所有请求参数)。此 url 将在 IdP 启动 SSO 的情况下自动使用。 - 在 ID 为
contextProvider
(org.springframework.security.saml.context.SAMLContextProviderLB
) 的 Bean 中,我们将 storageFactory 设置为org.springframework.security.saml.storage.EmptyStorageFactory
。这将禁用对 InResponseToField 的检查。