一个会话中的不同索赔

Different Claims in one Session

以下3种检索声明的方法有什么不同?

在 ApiController 中调用:

((ClaimsIdentity) HttpContext.Current.User.Identity).Claims
((ClaimsIdentity) Thread.CurrentPrincipal.Identity).Claims

((ClaimsIdentity) User.Identity).Claims

前两个属性存储了相同的数据,但最后一个属性存储了上一个会话的数据。

这是在注销方法中完成的:

UserCache.Instance.Clear();
FederatedAuthentication.SessionAuthenticationModule.SignOut();
HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);

更新

混合 WebForms、WebApi、MVC 应用程序

大部分应用程序是使用 WebForms 构建的。

如果您使用的是 WebApi,则 HttpContext.Current 不应直接可用 (see this answer)。所以我猜你也在使用 MVC 并且你在那里看到了 MVC 上下文。

Thread.CurrentPrincipal 使用起来很危险,因为它包含线程原理,这可能是您意想不到的,例如实际运行 IIS 的用户(AppPool 用户)。大多数时候它是你的想法,但有时它不是。这将导致你无休止地追逐错误,你永远无法重新创造自己。

User.Identity as ClaimsIdentity 是获得所需内容的正确方法,它在 VS 的默认模板中使用。但是,如果您看到来自 "previous session" 的数据 - 表示您的 cookie 未正确清除。您注销用户的方式看起来很可疑:

  1. 什么是 UserCache.Instance
  2. SignOut 方法在请求完成之前不会实际注销用户。因此,如果您调用它然后在同一个请求中检查用户身份,您将看到相同的身份完好无损。
  3. 分配 HttpContext.Current.User 不会在请求中给你太多。如果我们谈论的是纯 WebAPI,请参阅第一点。

默认注销是通过 IAuthenticationManager

完成的
    private IAuthenticationManager Authentication
    {
        get { return Request.GetOwinContext().Authentication; }
    }

    [Route("Logout")]
    public IHttpActionResult Logout()
    {
        Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
        return Ok();
    }

试试这个,然后根据您的需要进行调整。