【问题标题】:Authenticate an User.Identity from JWT从 JWT 验证 User.Identity
【发布时间】:2021-04-02 13:22:15
【问题描述】:

当我们在 POST 方法中将有效凭据发送到 api/signin 时,我有一个 API 会返回一个 JWT 作为字符串。

现在我想将我的 ASP.NET Core MVC 应用程序连接到此 API 以使用 User.IsAuthenticated 方法和 [Authorize] 注释。

为此,我正在尝试编写一个方法来解码 JWT 并创建声明以验证用户身份。这是给定的方法:

private async void Authenticate(string token)
{
    //Ask API if the token is valid
    if(await ClientService.ValidateJWTAsync(token))
    {
        //Extract claims from token
        var tokenHandler = new JwtSecurityTokenHandler();
        var securityToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

        var claimsIdentity = new ClaimsIdentity(securityToken.Claims, CookieAuthenticationDefaults.AuthenticationScheme);

        var authProperties = new AuthenticationProperties
        {
            IsPersistent = true,
        };

        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
    }
}

这背后的想法是,如果用户尝试访问 [Authorize] 视图,他将被重定向到(应用程序的 /signin 方法,该方法显示一个表单,然后将凭据发送到 api 以返回智威汤逊)。在这种方法中,我检查用户是否有一个名为“JWT”的 httpOnly Cookie,其中包含他的 JWToken。

如果用户有这个cookie,我将它发送到上面显示的Anthenticate 方法。如果他们有 JWT Cookie,它可以让我避免不断让我的用户输入他们的凭据。如果 httpOnly Cookie "JWT" 不存在,他们将不得不通过登录表单输入他们的凭据。

但是当我尝试执行此代码时,HttpContext.SignInAsync 调用时出现错误:

System.ObjectDisposedException: 'IFeatureCollection 已被释放。'

我不明白这里的问题。基本上,我添加到我的应用程序的唯一配置是在 Startup.cs 中:

ConfigureServices 方法:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie("CookieAuthentication", config =>
{
    config.Cookie.Name = "UserLoginCookie";
    config.LoginPath = "/SignIn";
});

配置方法:

app.UseAuthentication();
app.UseAuthorization();

我应该如何通过 JWT Cookie 对我的用户进行身份验证?

【问题讨论】:

    标签: c# asp.net-core jwt


    【解决方案1】:

    如果您打算使用 HttpContext,则不能在 Controller 中使用 async void 方法。 HttpContext 不是线程安全的,并且由于您返回 void,因此控制器不会等待您的登录完成,然后再返回和处理 HttpContext。

    这是因为该方法在第一个await 处返回给调用者,然后调用方法将在async void 方法的其余部分执行之前完成。

    Async void 的意思是“一劳永逸”,并且您不在乎之后会发生什么。在这种情况下,您依赖于异步方法等待之后发生的情况,因此您需要将其更改为异步任务。

    我还要说,你几乎从来不会不在乎发生了什么,除非你有非常充分的理由这样做,否则请避免使用async void 方法。

    改变这个:

    private async void Authenticate(string token)
    

    到这里:

    private async Task Authenticate(string token)
    

    并确保您的控制器方法已相应更改。

    查看此处了解更多信息: https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-3.1#do-not-use-the-httpcontext-after-the-request-is-complete

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 1970-01-01
      • 2015-11-15
      • 1970-01-01
      • 2020-11-07
      • 2023-03-12
      • 2018-11-08
      • 1970-01-01
      • 2021-10-03
      相关资源
      最近更新 更多