IdentityServer4 + OWIN客户端:注销请求不向外部IdP发送cookie(因为它是xh​​r)

时间:2020-07-03 10:48:03

标签: cookies owin identityserver4 adfs

设置

我有一个基于IdentityServer4的身份提供程序,并使用AD FS作为外部身份提供程序。

我有3种不同类型的客户:

  1. 基于OWIN lib的生产混合流客户端
  2. 测试混合流客户端(IdentityServer4存储库中的最新示例客户端)
  3. 隐式流客户端(Angular)

问题

测试客户端和隐式流客户端按预期工作。 从OWIN客户端注销时,用户是从我的IdP中注销的,而不是从AD FS中注销的。

一些分析

从OWIN客户端注销时,从AD FS注销时不发送cookie。因此,AD FS不会删除任何cookie,因此用户将保持登录状态。

最终的原因是,相应的请求是一个xhr请求,该请求无法发送cookie(尽管我们不使用SAML,也请参见SAML logout request is not sending cookies to IdP)。

总结一下,您可以在浏览器中观察到这些呼叫:

  1. 请求获取https:// myidp / connect / endsession
    查询参数 post_logout_redirect_uri = https:// xxx,id_token_hint = xxx,x-client-SKU = ID_NET45,x-client-ver = 5.5.0.0
    响应重定向到https:// myidp / account / logout?logoutId = xxx
  2. 请求获取https:// myidp / account / logout
    查询参数 logoutId = xxx
    响应重定向到https:// myadfs / oauth2 / logout?post_logout_redirect_uri = xxx&id_token_hint = xxx&state = xxx&x-client-SKU = ID_NETSTANDARD2_0&x-client-ver = 5.5.0.0
  3. 请求获取https:// myadfs / oauth2 / logout
    请求类型 xhr
    查询参数 post_logout_redirect_uri = xxx,id_token_hint = xxx,状态= xxx,x-client-SKU = ID_NETSTANDARD2_0,x-client-ver = 5.5.0.0
    回复

对于OWIN客户端,最后一次调用的类型为xhr,对于其他客户端,最后一次调用的类型为document。我认为客户端到myidp的初始调用中的某些内容必须有所不同,例如重定向链以xhr请求结尾。这是什么东西我该如何改变这种行为?

我仔细检查了每个呼叫的标题。我最怀疑的是Sec-Fetch-Header(其余的对于所有客户来说几乎是平等的),但我不知道他们实际上在做什么。

对于OWIN客户端:

Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty

对于其他客户:

Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document

我感谢任何提示!

1 个答案:

答案 0 :(得分:0)

post I cited above实际上是完全正确的:我们必须中断xhr重定向链,而改为执行常规的浏览器重定向。

但是,我们需要一些时间来弄清楚如何实现这一目标。这是我们的解决方案:

AuthorizationController中的Logout操作返回Redirect,我们必须用Ok响应替换它。这意味着替换

public class AuthorizationController : Controller
{
    public ActionResult Logout()
    {
      Request.GetOwinContext().Authentication.SignOut("Cookies");
      // ...Code for clearing cookies...
      return Redirect("/myroute");
    }    
}

作者

public class AuthorizationController : Controller
{
    public ActionResult Logout()
    {
      Request.GetOwinContext().Authentication.SignOut("Cookies");
      // ...Code for clearing cookies...
      return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
}