【问题标题】:Spring SAML sending wrong AuthNRequestSpring SAML 发送错误的 AuthNRequest
【发布时间】:2018-12-18 12:06:25
【问题描述】:

长期以来一直困扰着这个问题,感谢任何帮助。

我正在为我的应用程序实施 Spring SAML SSO 身份验证。 它实际上是一个巨大的安全配置文件,因此我只会附上我认为可能很重要的配置部分。

@Bean
    public MetadataGenerator metadataGenerator() {
        MetadataGenerator metadataGenerator = new MetadataGenerator();
        metadataGenerator.setEntityId(env.getProperty("saml.entity.id"));
        metadataGenerator.setExtendedMetadata(extendedMetadata());
        metadataGenerator.setIncludeDiscoveryExtension(false);
        metadataGenerator.setKeyManager(keyManager());
        return metadataGenerator;
    }

@Bean
    @Qualifier("idp-ssocircle")
    public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider() throws MetadataProviderException {
        String idpSSOCircleMetadataURL = env.getProperty("saml.provider.url");
        HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(this.backgroundTaskTimer, httpClient(),
                idpSSOCircleMetadataURL);
        httpMetadataProvider.setParserPool(parserPool());
        ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider,
                extendedMetadata());
        extendedMetadataDelegate.setMetadataTrustCheck(true);
        extendedMetadataDelegate.setMetadataRequireSignature(false);
        backgroundTaskTimer.purge();
        return extendedMetadataDelegate;
    }

我们在这个 bean 中使用的属性文件的值是 -

saml.entity.id=urn:saml2:test:s
saml.provider.url=https://fedsvc-stage.pwc.com/ofiss/FederationMetadata/2007-06/FederationMetadata.xml

我的 spring 应用程序托管在本地机器上,并且 IDP 是公开可用的。我在 hosts 文件中添加了条目,因此我的 ip 映射到 mysso.com

现在我正在尝试访问 SAML 身份验证背后的 url -

http://mysso.com:8080/sso-self/auth/login

用户 get 被重定向到他输入凭据的 IDP,并且在成功进行身份验证后,用户 get 被重定向回 - http://localhost:8080/sso-self/saml/SSO,带有 saml 响应,但我在浏览器上得到 404,并且在控制台上出现以下错误 -

org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message a330ei589j3e99ee10d8a55bghc518i

我可以看到的问题是消息正在从 2 个不同的会话中存储和检索,因为第一个请求来自域名 mysso.com 但响应返回到 localhost

这是我发送给 IDP 的 AuthnRequest XML

<?xml version="1.0" encoding="UTF-8"?><saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://localhost:8080/madison-sso-self/saml/SSO" Destination="https://fedsvc-stage.pwc.com/ofiss/" ForceAuthn="false" ID="a345ia5236e6hc2g48ea13fcf4386h7" IsPassive="false" IssueInstant="2018-12-18T07:46:41.812Z" 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">urn:saml2:test:s</saml2:Issuer>
</saml2p:AuthnRequest>

我能理解的是 AuthnRequest 中的 AssertionConsumerServiceURL 值是http://localhost:8080/madison-sso-self/saml/SSO,这就是它返回到这个 url 的原因。 现在我不明白为什么这个值是 localhost 而不是我的主机名 http://mysso.com:8080/madison-sso-self/saml/SSO

如果您需要更多信息来解决问题,请回复。 提前致谢。

【问题讨论】:

    标签: spring single-sign-on saml-2.0 spring-saml


    【解决方案1】:

    您可以使用 SAMLContextProviderLB 来解决此问题。请将以下配置中的值替换为您的服务器 URL。

    @Bean
    public SAMLContextProviderLB contextProvider() {
      SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
      samlContextProviderLB.setScheme("https");
      samlContextProviderLB.setServerName("www.myserver.com");
      samlContextProviderLB.setServerPort(443);
      samlContextProviderLB.setContextPath("/spring-security-saml2-sample");
      samlContextProviderLB.setStorageFactory(new EmptyStorageFactory());
      return samlContextProviderLB;
    }
    

    上述配置将使用https://www.myserver.com/spring-security-saml2-sample/saml/SSO 从 SAML 服务提供商重定向。

    samlContextProviderLB.setStorageFactory(new EmptyStorageFactory());
    

    以上行将有助于解决多会话问题。

    【讨论】:

      【解决方案2】:

      请参阅“spring-security-saml”文档中的以下段落: https://docs.spring.io/autorepo/docs/spring-security-saml/1.0.x-SNAPSHOT/reference/htmlsingle/#chapter-troubleshooting SSO 期间出现错误“InResponseToField 与发送的消息不对应”

      确保应用程序在发送请求和接收响应期间使用相同的 HttpSession。通常,当从 localhost 地址或 http 方案初始化身份验证请求时会出现此问题,而在公共主机名或 https 方案处收到响应。例如,从 URL https://host:port/app/saml/login 初始化身份验证时,必须在 https://host:port/app/saml/SSO 接收响应,而不是 http://host:port/ app/saml/SSO 或 https://localhost:port/app/saml/SSO。

      查看您是否可以使用相同的公共 DNS 名称而不是 localhost 访问应用程序

      【讨论】:

      • 嗨,如果您看到我附加的 saml 请求 AssertionConsumerServiceURL="localhost:8080/madison-sso-self/saml/SSO" AssertionCusumberServiceURL 正在作为 localhost 发送,这就是为什么它会在 localhost:8080 而不是 mysso.com:8080 上返回。这就是我无法弄清楚这个属性值是从哪里填充的。
      • 这可能是因为您访问您的应用程序表单 localhost:8080,如果您前面有负载均衡器或代理,那么您需要使用 SAMLContextProviderLB
      • 什么是“host;port”语法(分号而不是冒号)?是错字吗?
      • @lukas84 这是一个错字。谢谢
      • 我无法使其在 localhost 的测试部署中工作,即使我的第一个请求是对 locahost 完成的,并且也将一个请求返回到 localhost...无论如何,我该如何禁用该检查?我从来没有使用过securityContext.xml(设置那个EmptyStorageFactory)这可以用注释来完成吗?
      猜你喜欢
      • 2015-02-20
      • 2021-02-08
      • 1970-01-01
      • 2016-05-26
      • 1970-01-01
      • 2019-04-03
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多