Spring 使用 AWS SSO 作为 IdP 错误输入错误启动 SAML

Spring Boot SAML using AWS SSO as IdP errors with Bad Input

我想构建一个使用 Spring Boot 托管的站点,并且我想使用 AWS SSO 作为 SAML 身份提供商进行身份验证。我已经构建了一个 PoC 应用程序并尝试遵循 AWS 配置说明和我能找到的 Spring SAML 示例,但是当我浏览到我的站点(在本地主机上)时,AWS SSO 成功打开但随后失败并显示“错误输入” .

在我的 PoC 应用程序中(只有身份验证代码和索引页)我有:

spring:
  security:
    saml2:
      relyingparty:
        registration:
          metadata:
            signing.credentials:
                - private-key-location: classpath:key.pem
                  certificate-location: classpath:cert.pem
            identityprovider:
              metadata-uri: https://portal.sso.eu-west-1.amazonaws.com/saml/metadata/my-custom-applications-metadata-uri
@Bean
    RelyingPartyRegistrationResolver relyingPartyRegistrationResolver(
            RelyingPartyRegistrationRepository registrations) {
        return new DefaultRelyingPartyRegistrationResolver((id) -> registrations.findByRegistrationId("metadata"));
    }

    @Bean
    FilterRegistrationBean<Saml2MetadataFilter> metadata(RelyingPartyRegistrationResolver registrations) {
        Saml2MetadataFilter metadata = new Saml2MetadataFilter(registrations, new OpenSamlMetadataResolver());
        FilterRegistrationBean<Saml2MetadataFilter> filter = new FilterRegistrationBean<>(metadata);
        filter.setOrder(-101);
        return filter;
    }

我已经使用 SAML-tracer 插件来尝试弄清楚当我向 localhost:8080/ 发出请求时会发生什么。我们最终将 SAML POST(见下文)发送到 AWS,AWS 重新路由到 GET https://portal.sso.eu-west-1.amazonaws.com/token/whoAmI 成功,然后最终重新路由到 GET https://portal.sso.eu-west-1.amazonaws.com/saml/v2/assertion/very-long-id,失败并返回 400 Bad Request在 AWS SSO 的页面上,消息 {message: "Bad input", __type: "com.amazonaws.switchboard.portal#InvalidRequestException"} 出现问题。我尝试检查 CloudTrail 以查找更多信息,但它只记录事件 AssumeRoleWithSAML 后跟 ConsoleLogin ,这两个事件都成功了。这是 SAML-tracer 显示的 SAML 数据,我的应用程序 POSTs 到 AWS(可能敏感的替换信息):

<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                     AssertionConsumerServiceURL="http://localhost:8080/login/saml2/sso/metadata"
                     Destination="https://portal.sso.eu-west-1.amazonaws.com/saml/assertion/insert-long-id"
                     ID="a-long-id"
                     IssueInstant="2022-01-10T13:59:52.963Z"
                     ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                     Version="2.0"
                     >
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8080/saml2/service-provider-metadata/metadata</saml2:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <ds:Reference URI="#Anot-sure-if-secret-random-characters">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>some-more-characters</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>a-long-base-64-encoded-block-of-characters</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>a-long-encoded-certificate</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
</saml2p:AuthnRequest>

我试图找到有关 AWS SSO 如何期望发送数据或“错误输入”实际含义的更多信息,但确实很难找到。我还尝试了一些尝试在不使用我的 priv key/cert 签名的情况下发送请求,但这似乎并没有让我到任何地方。我怀疑 key/cert 过程有误,或者我没有正确设置 AWS,但我不确定如何继续。有人有什么想法吗?

问题是 ACS url 设置为 localhost。 ACS(断言消费者服务)URL 是 IdP 发送 SAML 断言的地方。

您要告诉 AWS SSO 将 SAML 断言发送给自己,这是行不通的。您的应用程序需要 public-routable IP。 AWS SSO 需要通过互联网发送 SAML 断言。

可能还有其他问题(我 运行 进入 ACS 问题后并没有真正检查任何内容)。但是 ACS URL 是您当前的问题。

错误是 IdP 证书未添加到 spring 应用程序。

为此,请在配置自定义应用程序时在 AWS SSO 中下载 AWS 证书,然后将该证书放在 src/main/resources/credentials/idp-certificate.crt

此步骤后一切正常,包括使用 localhost ACS URL。