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

时间:2015-01-05 11:47:34

标签: spring-security wso2 wso2is spring-saml

我已经采用了Spring SAML示例(参见4.2 in this guide),该示例与开源登录页面SSO一起使用,并尝试添加支持以使用WSO2 Identity Server作为额外的IDP服务。 为此,我通过为IS添加元数据xml文件来更改spring SAML示例项目,并将一个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文件(我必须给它一个'localhost'的entityID,因为这是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消息的日志。

1 个答案:

答案 0 :(得分:6)

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名称。您还可以在不同的域上部署应用程序(例如,通过在hosts文件中为您的localhost提供别名 - /etc/hosts%systemroot%\system32\drivers\etc\hosts