使用来自 Okta 的证书的 SAML 问题

SAML Issue Using Cert From Okta

我正在尝试将 Okta 集成到一个 spring 应用程序中,该应用程序已经实现了 spring 安全性。我已成功将 spring saml 添加到项目中,并且能够成功登录应用程序。但是它使用默认的 java 密钥存储,我想按照文档中的建议使用另一个 jks(http://docs.spring.io/spring-security-saml/docs/current/reference/html/security.html).

关于 spring saml 扩展在 jks 方面的工作方式,我有几个问题。

  1. 示例 jks 包含两个密钥。一个是 PrivateKeyEntry,一个是 trustedCertEntry。 "trustedCertEntry" 是应该从 IDP 收集的 public 密钥吗?
  2. 我认为 JKS 用于解密断言消息而不用于 https 握手。这个假设正确吗?

在使用提供的 JKS 与 apollo 和 startcom 时,我能够成功登录。但是,当我在 Okta 下的 SAML 配置中启用断言加密(加密算法:AES256-CBC,密钥传输算法:RSA-OAEP)时,它开始失败。我相信这是因为我没有使用 IDP 的 public 密钥,所以我获得了我的 Okta 证书文件。

我执行了以下操作来创建一个新的 jks 并导入证书文件:

keytool -genkeypair -alias self-signed -keypass default1! -keystore samlKeystore.jks

keytool -importcert -alias okta-pub -file okta.cert -keystore samlKeystore.jks

所以现在我的密钥库如下:

keytool -list -keystore samlKeystore.jks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

okta-pub, Jul 19, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): F2:2C:97:68:47:AF:17:B3:B0:9D:C0:07:09:2F:9A:90:DF:79:E5:CD
self-signed, Jul 19, 2016, PrivateKeyEntry,
Certificate fingerprint (SHA1): 99:21:35:CA:AA:AF:33:44:81:78:67:95:7A:1D:1D:6A:BA:5C:96:5D

我将我的安全上下文文件更新为:

    <bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="classpath:security/samlKeystore.jks"/>
    <constructor-arg type="java.lang.String" value="default1!"/>
    <constructor-arg>
        <map>
            <entry key="self-signed" value="default1!"/>
        </map>
    </constructor-arg>
    <constructor-arg type="java.lang.String" value="self-signed"/>
</bean>

当我尝试进行 SAML 登录时出现此异常:

[talledLocalContainer] 190716 12.43.03,777 {} {} {} ERROR (Decrypter.java:639) Failed to decrypt EncryptedKey, valid decryption key could not be resolved
[talledLocalContainer] 190716 12.43.03,777 {} {} {} ERROR (Decrypter.java:532) Failed to decrypt EncryptedData using either EncryptedData KeyInfoCredentialResolver or EncryptedKeyResolver + EncryptedKey KeyInfoCredentialResolver
[talledLocalContainer] 190716 12.43.03,778 {} {} {} ERROR (Decrypter.java:143) SAML Decrypter encountered an error decrypting element content
[talledLocalContainer] org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData

我已尝试使用此处提到的 JCE 无限强度库:Decrypting encrypted assertion using SAML 2.0 in java using OpenSAML。但这并没有解决我的问题。

有什么建议吗?我创建的 jks 文件是否正确?

编辑 1: 这是完整的堆栈跟踪:

[talledLocalContainer] 190716 13.45.27,717 {} {} {} ERROR (Decrypter.java:143) SAML Decrypter encountered an error decrypting element content
[talledLocalContainer] org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData
[talledLocalContainer]  at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:535) ~[xmltooling-1.4.1.jar:?]
[talledLocalContainer]  at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:442) ~[xmltooling-1.4.1.jar:?]
[talledLocalContainer]  at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:403) ~[xmltooling-1.4.1.jar:?]
[talledLocalContainer]  at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141) [opensaml-2.6.1.jar:?]
[talledLocalContainer]  at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69) [opensaml-2.6.1.jar:?]
[talledLocalContainer]  at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:199) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:87) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156) [spring-security-core-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:87) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at com.aspectsecurity.contrast.teamserver.security.auth.rest.RestAuthenticationFilter.doFilter(RestAuthenticationFilter.java:67) [RestAuthenticationFilter.class:?]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at com.aspectsecurity.contrast.teamserver.webapp.filter.WebSecurityFilter.doFilter(WebSecurityFilter.java:79) [WebSecurityFilter.class:?]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at com.aspectsecurity.contrast.teamserver.webapp.filter.ESAPIThreadLocalFilter.doFilter(ESAPIThreadLocalFilter.java:34) [ESAPIThreadLocalFilter.class:?]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71) [log4j-web-2.4.1.jar:2.4.1]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_79]
[talledLocalContainer]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_79]
[talledLocalContainer]  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at java.lang.Thread.run(Thread.java:745) [?:1.7.0_79]

The sample jks contains two keys. One which is PrivateKeyEntry and one is trustedCertEntry. Is the "trustedCertEntry" the public key that is supposed to be gathered from the IDP?

是的,来自您添加到密钥库的 IDP 的 public 证书将显示为 "trustedCertEntry"。

I believe that the JKS is used to decrypt assertion messages and not used for the https handshake. Is that assumption correct?

这是正确的。在这种情况下,JKS 不用于 https。

与文档所述相比,您生成密钥库的方式看起来是正确的。我最近使用以下内容生成了自己的密钥库:

--generate keystore
keytool -genkeypair -alias mysaml -keypass password -keystore samlKeystore.jks -keyalg RSA -keysize 2048
--export cert for import into IDP
keytool -export -keystore samlKeystore.jks -alias myalias -file mysaml.cer
--add cert form IDP
keytool -importcert -alias myidp -file myidp.cer -keystore samlKeystore.jks

我记得由于遇到一些加密错误而使用 RSA,但不记得它是否与您的问题相同。

我建议仔细检查 JCE 无限强度库的安装。很容易安装不正确,即如果您将其解压缩到错误的位置。