HTTP 状态 401 - 身份验证失败:解码传入 SAML 消息时出错
HTTP Status 401 - Authentication Failed: Error decoding incoming SAML message
我按照 spring saml tutorial 中的描述做了所有事情,除了我添加
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
在 pom.xml 中克服 w3.dom class 未找到的问题。当我 运行 示例项目时,我得到了
HTTP Status 401 - Authentication Failed: Error decoding incoming SAML message
在浏览器中,同时在控制台中 (CertPathPKIXTrustEvaluator.java:81) ERROR org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CN=idp.ssocircle.com' |credential entityID='https://idp.ssocircle.com']: unable to find valid certification path to requested target
。
包流屏幕截图:
第 2 天:
我 运行 keytool -importcert -alias identtrustca -file ca.cer -keystore samlKeystore.jks
并将 security/samlKeystore.jks
替换为新生成的。 securityContext.xml
:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="nalle123"/>
<constructor-arg>
<map>
<entry key="apollo" value="nalle123"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="apollo"/>
</bean>
那么我有:
Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
at org.springframework.security.saml.key.JKSKeyManager.initialize(JKSKeyManager.java:117)
... 57 more
Caused by: java.security.UnrecoverableKeyException: Password verification failed
... 61 more
然后我把密码改成使用时输入的密码 keytool
:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="123456"/>
<constructor-arg>
<map>
<entry key="apollo" value="123456"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="apollo"/>
</bean>
然后控制台说:
Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
java.lang.RuntimeException: Key for alias apollo not found
at org.springframework.security.saml.metadata.MetadataGenerator.getServerKeyInfo(MetadataGenerator.java:201)
所以我把apollo
改成identtrustca
:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="123456"/>
<constructor-arg>
<map>
<entry key="identtrustca" value="123456"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="identtrustca"/>
</bean>
控制台说:
Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
然后我读到this and this,所以我删除了入口元素(我相信它是私钥的东西),它变成了:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="123456"/>
<constructor-arg>
<map/>
</constructor-arg>
<constructor-arg type="java.lang.String" value="identtrustca"/>
</bean>
现在问题变成了:
Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
java.lang.RuntimeException: Key with alias identtrustca doesn't have a private key
第 2 天第 2 部分:
现在我明白了,与其创建新的密钥库,不如使用旧的 samlKeystore.jks。如果使用 keytool -list -V -keystore d:\temp\samlKeystore.jks
可以看到它包含 3 个项目(最初它有 2 个)。
我不明白为什么 SP 从 IdP 元数据中获取 public 密钥,但仍然需要 IdP 的 ca.cer?我相信来自 auth 网站的 ca.cer 是 IdP 的证书,尽管它与我通过 openssl s_client -connect idp.ssocircle.com:443 -showcerts
获得的不同
此外,现在我得到的不是 Error decoding incoming SAML message
,而是 HTTP Status 401 - Authentication Failed: Response issue time is either too old or with date in the future
第 3 天
当我启动 SP,从 chrome 和 firefox 访问 http://localhost:8080/spring-security-saml2-sample/ 时,当我在一个资源管理器中按下全局注销并刷新另一个时,它没有显示注销页面。我想对于 SSO,从同一个 SP 的全局注销应该忽略多会话,例如,一旦我在一个 "login" 中全局注销,我应该在另一个中自动注销,我应该看到一个注销-其他资源管理器中的页面(如果我刷新)。其实对于多个SP,一个我在一个注销,我曾经登录过的所有SP应该都能看到注销。
第 n 天
通过更改 saml 项目 url,需要修改 idp.ssocircle.com 中的元数据(管理元数据)。否则,idp 网站会显示错误。这是写在docs/reference/htmlsingle/index.html
IDP 元数据中的证书用于对 SAML XML 文档进行数字签名。您失败的证书来自 www.ssocircle.com 的 HTTPS 端点,您的 Spring SAML 在工件解析期间调用该端点。这两个证书通常不同。
SSOCircle 最近更改了为 www.ssocircle.com 颁发证书的证书颁发机构, 中描述的操作是让该 CA 受信任。
您最近的错误可能是由于您的 Spring SAML 机器上没有时间正确同步造成的。
我按照 spring saml tutorial 中的描述做了所有事情,除了我添加
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
在 pom.xml 中克服 w3.dom class 未找到的问题。当我 运行 示例项目时,我得到了
HTTP Status 401 - Authentication Failed: Error decoding incoming SAML message
在浏览器中,同时在控制台中 (CertPathPKIXTrustEvaluator.java:81) ERROR org.springframework.security.saml.trust.MetadataCredentialResolver - PKIX path construction failed for untrusted credential: [subjectName='CN=idp.ssocircle.com' |credential entityID='https://idp.ssocircle.com']: unable to find valid certification path to requested target
。
包流屏幕截图:
第 2 天:
我 运行 keytool -importcert -alias identtrustca -file ca.cer -keystore samlKeystore.jks
并将 security/samlKeystore.jks
替换为新生成的。 securityContext.xml
:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="nalle123"/>
<constructor-arg>
<map>
<entry key="apollo" value="nalle123"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="apollo"/>
</bean>
那么我有:
Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
at org.springframework.security.saml.key.JKSKeyManager.initialize(JKSKeyManager.java:117)
... 57 more
Caused by: java.security.UnrecoverableKeyException: Password verification failed
... 61 more
然后我把密码改成使用时输入的密码 keytool
:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="123456"/>
<constructor-arg>
<map>
<entry key="apollo" value="123456"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="apollo"/>
</bean>
然后控制台说:
Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
java.lang.RuntimeException: Key for alias apollo not found
at org.springframework.security.saml.metadata.MetadataGenerator.getServerKeyInfo(MetadataGenerator.java:201)
所以我把apollo
改成identtrustca
:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="123456"/>
<constructor-arg>
<map>
<entry key="identtrustca" value="123456"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="identtrustca"/>
</bean>
控制台说:
Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
然后我读到this and this,所以我删除了入口元素(我相信它是私钥的东西),它变成了:
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="123456"/>
<constructor-arg>
<map/>
</constructor-arg>
<constructor-arg type="java.lang.String" value="identtrustca"/>
</bean>
现在问题变成了:
Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2-sample] threw exception
java.lang.RuntimeException: Key with alias identtrustca doesn't have a private key
第 2 天第 2 部分:
现在我明白了,与其创建新的密钥库,不如使用旧的 samlKeystore.jks。如果使用 keytool -list -V -keystore d:\temp\samlKeystore.jks
可以看到它包含 3 个项目(最初它有 2 个)。
我不明白为什么 SP 从 IdP 元数据中获取 public 密钥,但仍然需要 IdP 的 ca.cer?我相信来自 auth 网站的 ca.cer 是 IdP 的证书,尽管它与我通过 openssl s_client -connect idp.ssocircle.com:443 -showcerts
此外,现在我得到的不是 Error decoding incoming SAML message
,而是 HTTP Status 401 - Authentication Failed: Response issue time is either too old or with date in the future
第 3 天 当我启动 SP,从 chrome 和 firefox 访问 http://localhost:8080/spring-security-saml2-sample/ 时,当我在一个资源管理器中按下全局注销并刷新另一个时,它没有显示注销页面。我想对于 SSO,从同一个 SP 的全局注销应该忽略多会话,例如,一旦我在一个 "login" 中全局注销,我应该在另一个中自动注销,我应该看到一个注销-其他资源管理器中的页面(如果我刷新)。其实对于多个SP,一个我在一个注销,我曾经登录过的所有SP应该都能看到注销。
第 n 天 通过更改 saml 项目 url,需要修改 idp.ssocircle.com 中的元数据(管理元数据)。否则,idp 网站会显示错误。这是写在docs/reference/htmlsingle/index.html
IDP 元数据中的证书用于对 SAML XML 文档进行数字签名。您失败的证书来自 www.ssocircle.com 的 HTTPS 端点,您的 Spring SAML 在工件解析期间调用该端点。这两个证书通常不同。
SSOCircle 最近更改了为 www.ssocircle.com 颁发证书的证书颁发机构,
您最近的错误可能是由于您的 Spring SAML 机器上没有时间正确同步造成的。