当前位置: 首页 > 知识库问答 >
问题:

将Spring SAML集成为SP,将SimpleSAMLphp集成为IdP(HoK配置文件)

蔚学林
2023-03-14

我试图让HoK配置文件与Spring SAML作为SP和SimpleSAMLphp作为IdP一起工作。

SP获取客户端证书,然后向IdP发送以下身份验证请求,无问题:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest
    AssertionConsumerServiceURL="https://sp.com/saml/HoKSSO"
    Destination="https://localhost:8443/simplesaml/saml2   /idp/SSOService.php"
    ForceAuthn="false" ID="a5ba2704fgc63887442i9i1298904fh"
    IsPassive="false" IssueInstant="2015-10-04T11:26:47.393Z"
    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://sp.com/saml/metadata</saml2:Issuer>
</saml2p:AuthnRequest>

作为响应,IdP在TLS握手期间请求客户端证书,然后获取他的用户名/密码并成功验证他。它发送以下响应:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response Destination="https://sp.com/saml/HoKSSO"
    ID="_94c3201b7ae79d95f8ef289705c406bd61b8ed81f1"
    InResponseTo="a5ba2704fgc63887442i9i1298904fh"
    IssueInstant="2015-10-04T11:26:47Z" Version="2.0"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <saml:Issuer>https://localhost:8443/simplesaml/saml2/idp/metadata.php</saml:Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion ID="_b703fd12c6692e7a5d431d539888fcb01171a41f92"
        IssueInstant="2015-10-04T11:26:47Z" Version="2.0"
        xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <saml:Issuer>https://localhost:8443/simplesaml/saml2/idp/metadata.php</saml:Issuer>
        <saml:Subject>
            <saml:NameID
                Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" SPNameQualifier="https://sp.com/saml/metadata">b9bdc06e4c25f5a464c6d5586394d6922031bd1d</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:holder-of-key">
                <saml:SubjectConfirmationData
                    InResponseTo="a5ba2704fgc63887442i9i1298904fh"
                    NotOnOrAfter="2015-10-04T11:31:47Z" Recipient="https://sp.com/saml/HoKSSO">
                    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                        <ds:X509Data>
                            <ds:X509Certificate>MIIFiDCCA3CgAwIBAgIQbAEaDQN5v8UJ7CM03ArefzANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJJUjEYMBYGA1UECgwPSXJhbiBHb3Zlcm5tZW50MSAwHgYDVQQDDBdUZXN0QmVkMiBJUkFOIEFkbWluIENBMTAeFw0xMzExMTExMjQyNTdaFw0xNTExMTExMjQyNTdaMEsxCzAJBgNVBAYTAklSMQ0wCwYDVQQKDAROT0NSMRYwFAYDVQQDDA1oIGFtaXJpIC0gU0NMMRUwEwYDVQQFEwxpcjA1Njk5NTk1OTQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSTKy+pttM92iH9EIo5eBiI8aJRTfLAUrjY7Wsts4qJjj08CCrYsFdw6PLVFRhOCG8xK1YXQ+vgl3FBFDrJVj3Gg43izirUoDANCGIvABMrOekRfR62YRDpah7A8e4tA27Uo7WBPqhISClyUvRifDZSYVsf08vQZCE48jEUpaxDhhLW1gED82a5dGDbR9S6PauVLsSR4z4mkPGMxLiERIgTimcpUyt1bMRcFGAQIQs0NGNssH6CHOWWBfPICFwixvoejWjMjgwWCNGBuQduuIu2nqYIJ5eoNh+8kUIcS77RTcNZnUki8fkbIvZpl9yuS85L8OADfThf+AZpPCXar0RAgMBAAGjggFoMIIBZDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQogn5DJWYIWEPWrkh1e7hZWqBApDAfBgNVHSMEGDAWgBQgILBuWsWyApOxBN+fWtk5GuDPjjAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0gBAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAgYKKwYBBAGCNxQCAjA9BgNVHREENjA0gRRpcjA1Njk5NTk1OTRAaXJhbi5pcqAcBgorBgEEAYI3FAIDoA4MDGlyMDU2OTk1OTU5NDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vQ1JMRFBUb0JlRGVmaW5lZC9BUkwvVGVzdEJlZDJJUkFOQWRtaW5DQTEuY3JsMFIGCCsGAQUFBwEBBEYwRDBCBggrBgEFBQcwAoY2aHR0cDovL3BrZC5pcmFuaWQuaXIvL0NBQ2VydHMvVGVzdEJlZDJJUkFOQWRtaW5DQTEuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQBoxP6xmLLdNCsdQ1S6cP/ZhadtCXiVdnvjnQOr43iTHRwdHIcGuQyMpmOQFAi/IhvPMWXK2DAnCW3UQi4csZpAl0MtRQU+BpCOzb47sihqxJX69hKXQQUHRYpyzAXBoA0yFfqKM/Q1MoqqZD/z4y3Anma7vF1vlGqWYRqHSY/jSa+10IlEw4WHC24FCw06Tz8w2h3MFfrzB+vDBZ6jndy5c2+XEFdIGdk/8QFYndkC9lfrpfVDEl8Qq6P+dyZPIA8fFCfE/4qadhMsytU9bmwq92K3/wXKjg0dnJJte+zC9O8qqCU5aBmIIGiaB5NIQaSmZXMFeFcgwKzPtyUZVOosTyeDwrhDiSaup2EU2UapGlPyl6FM6BrGu1gdSRSjOJd2YOM0y7GFP/2TqImLC7wREI5eK/zjDZyNjE5XOA7eZkODgZy+sD5Zj9pKsZYCQxRSZe16awnIZ5QWERVUNKjQgm9BPx1evLE4rCxj6e1aorecR/uJjKtUjuJNxF+DI83Rnj3TBIzyxPM0YEB8iro0qBzEO6MVnVR251qYpN0Mu3qHJk9kHa+RwK7gpIiC/gqN/u/O+D4h0tFJ/dfE6UP3SR0et/Hs3Yby0hhyt3C7UgXHEyVGSkyr1yYUrdQK2Qyoktv9xCqUwZ+OFiHECBC9ZaF8kqPi9VsVqf5OjX9TQg==</ds:X509Certificate>
                        </ds:X509Data>
                    </ds:KeyInfo>
                </saml:SubjectConfirmationData>
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2015-10-04T11:26:17Z" NotOnOrAfter="2015-10-04T11:31:47Z">
            <saml:AudienceRestriction>
                <saml:Audience>https://sp.com/saml/metadata</saml:Audience>
            </saml:AudienceRestriction>
        </saml:Conditions>
        <saml:AuthnStatement AuthnInstant="2015-10-04T11:08:06Z"
            SessionIndex="_2e1ddd44e4b2215a074312dc7a1e31865dd940f49f" SessionNotOnOrAfter="2015-10-04T19:26:47Z">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
        <saml:AttributeStatement>
            <saml:Attribute Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
                <saml:AttributeValue xsi:type="xs:string">student</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
                <saml:AttributeValue xsi:type="xs:string">member</saml:AttributeValue>
                <saml:AttributeValue xsi:type="xs:string">student</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>

看起来一切正常,但是Spring SAML抛出了以下异常:

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:167)
at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:87)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:184)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:152)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.security.web.debug.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:75)
at org.springframework.security.web.debug.DebugFilter.doFilter(DebugFilter.java:62)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:221)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:107)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:76)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:934)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:90)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:515)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1012)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:642)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1555)
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:744)
Caused by: org.opensaml.common.SAMLException: Response doesn't have any valid assertion which would pass subject validation
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:229)
at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:84)
... 43 more
Caused by: org.opensaml.common.SAMLException: Assertion invalidated by subject confirmation - can't be confirmed by holder-of-key method
at org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl.verifySubject(WebSSOProfileConsumerHoKImpl.java:150)
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.verifyAssertion(WebSSOProfileConsumerImpl.java:296)
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:214)
... 44 more

Spring SAML调试日志在此处:

8532 [http-nio-443-exec-9] DEBUG   - Evaluating security policy of type 'org.opensaml.ws.security.provider.BasicSecurityPolicy' for decoded message
8532 [http-nio-443-exec-9] DEBUG   - Evaluating simple signature rule of type: org.opensaml.saml2.binding.security.SAML2HTTPPostSimpleSignRule
8532 [http-nio-443-exec-9] DEBUG   - HTTP request was not signed via simple signature mechanism, skipping
8532 [http-nio-443-exec-9] INFO    - SAML protocol message was not signed, skipping XML signature processing
8532 [http-nio-443-exec-9] DEBUG   - Successfully decoded message.
8532 [http-nio-443-exec-9] DEBUG   - Checking SAML message intended destination endpoint against receiver endpoint
8533 [http-nio-443-exec-9] DEBUG   - Intended message destination endpoint: https://cmks.irannid.ir/saml/HoKSSO
8533 [http-nio-443-exec-9] DEBUG   - Actual message receiver endpoint: https://cmks.irannid.ir/saml/HoKSSO
8533 [http-nio-443-exec-9] DEBUG   - SAML message intended destination endpoint matched recipient endpoint
8533 [http-nio-443-exec-9] DEBUG   - Found endpoint org.opensaml.saml2.metadata.impl.AssertionConsumerServiceImpl@38620660 for request URL https://cmks.irannid.ir/saml/HoKSSO based on location attribute in metadata
8534 [http-nio-443-exec-9] DEBUG   - Authentication attempt using org.springframework.security.saml.SAMLAuthenticationProvider
8534 [http-nio-443-exec-9] DEBUG   - Verifying issuer of the Response
8535 [http-nio-443-exec-9] DEBUG   - Processing Holder-of-Key subject confirmation
8535 [http-nio-443-exec-9] DEBUG   - HoK SubjectConfirmation invalidated by confirmation data not being of KeyInformationDataType type
8535 [http-nio-443-exec-9] DEBUG   - Validation of authentication statement in assertion failed, skipping

错误为:HoK SubjectConfirmation因确认数据不属于KeyInformationDataType类型而无效。好像Spring SAML在响应里找不到KeyInfo!!

有人能帮我解决这个问题吗?

谢谢你

编辑:

通过与示例HoK SSO响应的比较,可以看出SimpleSAMLphp没有在SubjectConfirmationData标签中添加xsi: type="saml: KeyInfoConfirmationDataType"。会是上述异常的原因吗?

它是SAML2.0 HoK配置文件中SubjectConfirmationData标签的强制属性吗?

共有1个答案

申屠新觉
2023-03-14

最后我找到了解决方案:

SimpleSAMLphp不会将xsi: type="saml: KeyInfoConfirmationDataType"添加到“SubjectConfirmationData”标签中,因为标准没有强制要求它:

329  3.1 Holder of Key
330  URI: urn:oasis:names:tc:SAML:2.0:cm:holder-of-key
331  One or more <ds:KeyInfo> elements MUST be present within the <SubjectConfirmationData>
332  element. An xsi:type attribute MAY be present in the <SubjectConfirmationData> element and, if
333  present, MUST be set to saml:KeyInfoConfirmationDataType (the namespace prefix is arbitrary but
334  must reference the SAML assertion namespace). 

我更改了simplesamlphp代码,并手动添加了缺少的属性。(我仍然不确定我添加的位置是否正确,但它现在已经起作用了!)但新的问题是谁必须解决这个问题?Spring SAML还是simpleSAMLphp?

通过此更改,Spring SAML检测到SubjectConfirmationData标签包含一个或多个元素,然后它会找到嵌入在响应中的客户端证书,并尝试将其与TLS客户端身份验证期间收到的证书进行比较。

虽然这两个证书是相同的,但Spring SAML说它们不匹配,因为其中一个有换行符,另一个没有。

我唯一剩下的问题是:

哪种方法与标准兼容?在base64编码的证书中添加断行还是删除它们,甚至比较有没有断行?

 类似资料:
  • 为了在我的webapp中支持SSO和SLO,我使用Spring Security SAML扩展实现了一个服务提供商。 代码在GitHub上可用:vdenotaris/spring-boot-saml。 通过使用ssocycle作为身份提供者,一切都很好。 现在,我正在尝试链接另一个基于简单SAML的IdP,在这种情况下,SSO失败了。 通过分析我的应用程序服务器(Apache Tomcat 7.0

  • 问题内容: 我有一个主要使用Richfaces的JSF应用程序。我想介绍一个功能更丰富的网格控件,例如基于jQuery的jqgrid。是否可以从JSF支持bean获得JSON数据?如果没有,是否有替代方法? 问题答案: 这里可能有几个选择。 Bean方法可以返回一个字符串,它只是一个JSON字符串 您可以使用JsonLib将Java对象转换为Json。 使用其他Servlet服务网格请求 我将推荐

  • 问题内容: 我已经下载并安装了Spring工具套件。现在,当我尝试在IntelliJ中创建新项目时,它在库中没有显示Spring。如何在其中获取Spring? 提前致谢! 问题答案: 在SpringSource工具套件具有无关的IntelliJ IDEA ,实际上它是一个不同的IDE(这是一个专门的Eclipse分布)。 因此,尽管下载Spring 框架 确实有意义(尽管最好通过Maven之类的构

  • 我试图从jsf启动激活引擎 引擎总是以null返回,我读到activiti.cfg.xml文件应该在类路径中,我已经把文件放在web-inf/class下,但是引擎仍然返回null,这意味着激活不能初始化引擎,有什么想法吗?

  • 我想在PyCharm中运行ROS,但是找不到。应该在其中进行更改的桌面文件。此外,我想使用为< code>PyTorch创建的相同环境,不想更改解释器。有人能帮我一下吗? 问候。

  • 我使用SSOCIRCE实现了Spring SAML示例应用程序,效果很好。现在我一直在尝试为客户的ADF实现它。以下是我认为需要的配置,如果我错了,请纠正我: 将下面的第一个参数更改为federationMetadata。客户端提供的xml url 我还没有弄明白以下几点: 我只收到了adfs/的url/联邦元数据。xml,谁应该创建SP元数据 我是否应该创建SP元数据并提供给客户端,以便将其添加