Spring SAML 与 WSO2 身份服务器集成,无法识别 SAML 消息

Posted

技术标签:

【中文标题】Spring SAML 与 WSO2 身份服务器集成,无法识别 SAML 消息【英文标题】:Spring SAML integration with WSO2 Identity server, SAML Message ID not reconised 【发布时间】:2015-03-02 22:52:22 【问题描述】:

我采用了 Spring SAML 示例(参见第 4.2 节 in this guide),它与开源登录页面 SSO 一起使用,并尝试添加支持以将 WSO2 Identity Server 用作附加 IDP 服务。 为此,我更改了 spring SAML 示例项目,为 IS 添加了一个元数据 xml 文件,并将 IS 元数据的条目添加到 securityContext.xml。

在运行 spring 应用程序时,我现在看到一个使用 IS 登录的选项,当我被重定向到 WSO2 时,我可以成功登录它。但是,spring 应用程序在 IS SAML 响应上引发异常,因为它与 InResponseToField 不匹配。

2015-01-05 09:54:12,845 line="org.springframework.security.saml.log.SAMLDefaultLogger.log(SAMLDefaultLogger.java:127)" thread="http-nio-8080-exec-4" class="org.springframework.security.saml.log.SAMLDefaultLogger" AuthNResponse;FAILURE;0:0:0:0:0:0:0:1;com:vdenotaris:spring:sp;localhost;;;org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message ae2dab0fb8b0g8e49971b91a73e91i

从调试应用程序看来,响应消息未被识别为与请求消息属于同一会话。我说从这两条日志消息中,第一条是在发送 AuthRequest 时记录的,第二条是在收到响应时记录的:

2015-01-05 09:53:20,867 line="org.springframework.security.saml.storage.HttpSessionStorage.storeMessage(HttpSessionStorage.java:93)" thread="http-nio-8080-exec-1" class="org.springframework.security.saml.storage.HttpSessionStorage" Storing message ae2dab0fb8b0g8e49971b91a73e91i to session 26D3B7D9E33F26A7A5092BF6909B9D13
...
2015-01-05 09:54:10,731 line="org.springframework.security.saml.storage.HttpSessionStorage.retrieveMessage(HttpSessionStorage.java:117)" thread="http-nio-8080-exec-4" class="org.springframework.security.saml.storage.HttpSessionStorage" Message ae2dab0fb8b0g8e49971b91a73e91i not found in session BBF256F284F55D774E6997600E9B3388

IS SAML 响应是:

<?xml version="1.0" encoding="UTF-8"?><saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:8080/saml/SSO" ID="adlbklpnldoanfphalcaahhacooinnldcejjjioe" InResponseTo="ae2dab0fb8b0g8e49971b91a73e91i" IssueInstant="2015-01-05T09:53:38.063Z" Version="2.0">
   <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer>
   <saml2p:Status>
      <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
   </saml2p:Status>
   <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="ebhfkdhlgbhclcklefjigfddoikklhjlanlbolel" IssueInstant="2015-01-05T09:53:38.065Z" Version="2.0">
      <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer>
      <saml2:Subject>
         <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">smit005</saml2:NameID>
     <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml2:SubjectConfirmationData InResponseTo="ae2dab0fb8b0g8e49971b91a73e91i" NotOnOrAfter="2015-01-05T09:58:38.063Z" Recipient="http://localhost:8080/saml/SSO"/>
     </saml2:SubjectConfirmation>
  </saml2:Subject>
  <saml2:Conditions NotBefore="2015-01-05T09:53:38.065Z" NotOnOrAfter="2015-01-05T09:58:38.063Z">
     <saml2:AudienceRestriction>
        <saml2:Audience>com:vdenotaris:spring:sp</saml2:Audience>
     </saml2:AudienceRestriction>
  </saml2:Conditions>
  <saml2:AuthnStatement AuthnInstant="2015-01-05T09:53:38.068Z" SessionIndex="406d4530-6fcf-4edf-b876-a68de4b4ea79">
     <saml2:AuthnContext>
            <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef>
     </saml2:AuthnContext>
  </saml2:AuthnStatement>
  <saml2:AttributeStatement/>
   </saml2:Assertion>
</saml2p:Response>

作为参考,我附上了我为 WSO2 IS 添加的元数据 xml 文件(我必须给它一个 entityID 'localhost',因为这是 WSO2 IS 坚持返回的(它默认使用主机名))。

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
                     entityID="localhost"
                     validUntil="2023-09-23T06:57:15.396Z">
   <md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" >
    <md:KeyDescriptor use="signing">
        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJVUzELMAkGA1UE
                    CAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoMBFdTTzIxEjAQBgNVBAMMCWxv
                    Y2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAyMTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQsw
                    CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UE
                    AwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTou
                    sMzOM4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5
                    HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQID
                    AQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEAW5wPR7cr1LAdq+IrR44i
                    QlRG5ITCZXY9hI0PygLP2rHANh+PYfTmxbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJR
                    O4d1DeGHT/YnIjs9JogRKv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=</ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </md:KeyDescriptor>
        <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:9443/samlsso" ResponseLocation="https://localhost:9443/samlsso"/>
        <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:9443/samlsso"/>
        <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:9443/samlsso"/>
       <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
       <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
       <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
       <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
   </md:IDPSSODescriptor>
</md:EntityDescriptor>

根据要求,我已在 dropbox 上保存了浏览器 HTTP 消息日志。

【问题讨论】:

您能否在单点登录过程中包含通过浏览器的 HTTP 消息转储? 您好弗拉基米尔,我已经添加了浏览器消息日志的链接。 【参考方案1】:

Spring SAML 和您的 IDP WSO2 服务器都部署在同一个域 - localhost。这就是发生的事情:

Spring SAML 创建一个 HTTP 会话 (JSESSIONID - 82F3ECD1A1E4F9B7DB0134F3129267A5) 并初始化单点登录 WSO2 接受请求并对用户进行身份验证,但会创建自己的会话 (JSESSIONID -C34B21931C53080487B5B9BA6EB490D2) 并将用户重定向回 Spring SAML 运行 Spring SAML 的容器接收带有 JSESSIONID (C34B21931C53080487B5B9BA6EB490D2) 的 cookie,但由于它无法识别此类会话,它会创建一个新会话 (E712A8422009613F6FD3901327690726) Spring SAML 尝试根据原始请求验证收到的 SAML 消息,但由于原始会话现已消失,因此无法找到它

解决此问题的最简单方法是更改​​ Spring SAML 或 WSO2 的会话 cookie 名称。您还可以在不同的域上部署您的应用程序(例如,通过在主机文件中为您的 localhost 指定一个别名 - /etc/hosts%systemroot%\system32\drivers\etc\hosts

【讨论】:

确实是这个问题,最后我设置wso2在VM中运行。这比让它使用另一个域更容易。 @vladimír-schäfer,我们如何设法更改 Spring SAML 的会话 cookie 名称? 作为 Spring Security 的一部分 - 请参阅此处***.com/questions/29964921/…

以上是关于Spring SAML 与 WSO2 身份服务器集成,无法识别 SAML 消息的主要内容,如果未能解决你的问题,请参考以下文章

wso2 spring security saml 无状态集成

春季 SAML wso2

我如何针对来自身份服务器的 SAML 断言授权用户(Wso2is 5.4.0)

WSO2 和 Spring SAML 单次注销问题

在没有浏览器的情况下对WSO2 Identity Server进行身份验证,并获取SAML2断言消息

WSO2 IS Facebook 用户在 SAML 响应中的角色