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

Spring Security SAML一次登录全局单次注销LogoutRequest解析问题

缑永年
2023-03-14

我正在用一个登录名实现Spring Security SAML。我已经设置了所有的配置文件和元数据

我能够得到登录工作和注销工作,如果我退出我登录的同一个应用程序.在这种情况下,从SAML IDP我得到LogoutResponse和Spring Security是能够解析和处理它。

http://localhost:8080/web/saml/SingleLogout?SAMLResponse=..............

问题是当我在两个应用程序中登录时,当前我登录到一个登录管理控制台,有一个指向我的应用程序的链接,我点击它,我可以直接登录到我的应用程序中,现在当我从一个登录管理控制台注销时,我的应用程序得到LogoutRequest。

http://localhost:8080/web/saml/SingleLogout?SAMLRequest=.........

Spring Security会很好地解析它,并将对象传递给验证检查逻辑。

org.springframework.security.saml.websso.processLogoutRequest(SAMLMessageContext context, SAMLCredential credential)

此方法具有以下检查。

// Make sure request was authenticated if required, authentication is done as part of the binding processing
        if (!context.isInboundSAMLMessageAuthenticated() && context.getLocalExtendedMetadata().isRequireLogoutRequestSigned()) {
            throw new SAMLStatusException(StatusCode.REQUEST_DENIED_URI, "LogoutRequest is required to be signed by the entity policy");
        }

我试图跟踪跟踪,但上下文对象的字段inboundSAMLMessageAuthenticated从未设置为true。上述检查失败并引发异常。

在调试模式下,我将值显式更改为true,它继续进行,但还有一个问题。

同样的方法还有另一种检查。

try {
            // Fail if NameId doesn't correspond to the currently logged user
            NameID nameID = getNameID(context, logoutRequest);
            if (nameID == null || !equalsNameID(credential.getNameID(), nameID)) {
                throw new SAMLStatusException(StatusCode.UNKNOWN_PRINCIPAL_URI, "The requested NameID is invalid");
            }
        } catch (DecryptionException e) {
            throw new SAMLStatusException(StatusCode.RESPONDER_URI, "The NameID can't be decrypted", e);
        }

方法equalNameId如下所示。

private boolean equalsNameID(NameID a, NameID b) {
        boolean equals = !differ(a.getSPProvidedID(), b.getSPProvidedID());
        equals = equals && !differ(a.getValue(), b.getValue());
        equals = equals && !differ(a.getFormat(), b.getFormat());
        equals = equals && !differ(a.getNameQualifier(), b.getNameQualifier());
        equals = equals && !differ(a.getSPNameQualifier(), b.getSPNameQualifier());
        equals = equals && !differ(a.getSPProvidedID(), b.getSPProvidedID());
        return equals;
    }

在这里,它在difference(a.getFormat(),b.getFormat())上失败

问题

我不确定我是否遗漏了什么,有点迷失了在哪里检查以解决这个问题。

我的单次注销绑定是HTTP重定向。

如果能提供指导,我们将不胜感激。如果需要更多信息,请告诉我。

谢谢你抽出时间。

堆栈(遗留应用程序):

Spring3.0.6

Spring Security 3.1.2

Spring Security SAML 1.0.0

Tomcat 7。十、

共有1个答案

皇甫聪
2023-03-14

在最初的帖子发布两年后,我遇到了这个问题,我不得不做一些进一步的研究。关于SAML规范,我还有一些阅读工作要做,但我想我在SAML 2.0勘误表中找到了一条关于NameID类型结构的条目,它是NameID和Issuer的基础。此类型中的所有四个元素都是可选的。OneLogin似乎遵循此文档,并且不发送NameID。在SingleLogout请求中设置格式。

因此,inboundMessage的nameID格式为null,而凭证的nameID格式为“urn:oasis:names:tc:SAML:1.1:nameIDhtml" target="_blank">格式:emailAddress”。这就是导致getFormat行返回false并使整个检查失败的原因。

 类似资料:
  • 您好,我在ADFS 2.0中面临以下单一注销问题。 我使用ADFS 2.0作为RST,另一个ADFS 2.0注册为声明提供程序,并配置为表单身份验证。 我有4个依赖方(RPs)托管在另一台IIS服务器上。 在对索赔提供者进行身份验证后,我正在打开IE中的所有4个RPs。注销第一次运行得非常好。但如果我再次登录并单击注销,则刷新后任何一个RP应用程序都会保持登录状态。我还可以看到,在ADFS/LS站

  • 我有一个关于SAML 2.0和SLO的问题<在SLO过程中,作为Idp,我们启动注销并向SP发送注销请求,SP则返回注销响应。我们在IDP端部分注销,用户在IDP端注销,但是如果我返回SP站点,我仍然登录<这是IdP侧还是SP侧的问题?我的意思是SP应该终止会话并向IDP发送注销响应,还是IDP的任务是终止双方的会话? 谢啦

  • 我已经使用spring-saml建立了一个联合。SSO过程工作正常,但是我有一个单一注销的问题。 问题#1是,在我从SP调用saml/注销后,它从Idp注销,也从我的SP注销,但它不会重定向到Idp登录页面。 问题#2是,当我让其他SP参与处理我的SP时,我的SP不知何故断开了链,它将其他SP引导到我的SP注销页面,而不是Idp注销页面。 这是我的配置: 这是我的日志: 有人能帮我设置配置吗 谢啦

  • 我正试图在我的java webapp中实现WSO2单点注销功能<我无法理解这件事: 然后我为第一个服务提供商(SP)调用注销,IdP使用SAML响应将其重定向到某个注销url,SP收到此请求并使超文本传输协议会话无效。 第二个SP也使用SAML响应从IdP获取请求,但此请求中的http会话是IdP和SP之间的会话,我需要使web浏览器和SP之间的会话无效。我如何获取此会话?

  • 我正在使用带有java配置和两个HttpSecurity配置的spring-security 3.2.0.rc2。一个用于REST API,一个用于UI。当我发布到/logout时,它重定向到/login?logout,但随后(错误地)重定向到/login。当我成功地输入用户名和密码时,我会被重定向到登录-注销,并且必须再次输入凭据才能进入主页面。因此,似乎login的permitAll不被用于l

  • 我已经构建了两个keycloak客户机(spring-client和一个tomcat-client,使用keycloak、OIDC、spring boot adapter和OIDC、tomcat adapter),它们都在同一领域工作。我和这些客户有两个问题。 当我要登录到这些客户端时,我需要分别为每个客户端提供用户名和密码,即使我使用的是相同的浏览器(多个选项卡)和相同的用户名。 当我需要注销时