问题

我有一个API,当我们在POST方法中向API/signin发送有效凭证时,它返回一个JWT作为字符串。

现在我想将我的ASP.NET核心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)。在这个方法中,我检查用户是否有一个名为“JWT”的httpOnly Cookie,其中包含他的JWToken。

如果用户有这个cookie,我将它发送到上面显示的Anthenticate方法。如果用户有JWT Cookie,它允许我避免不断地让他们输入凭据。如果httpOnly Cookie“JWT”不存在,则他们必须通过登录表单输入凭据。

但是当我尝试执行这段代码时,HttpContext.SignInAsync调用出现了一个错误:

System.ObjectDisposedException:'IFeatureCollection已disposed.'

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

ConfigureServices方法:

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

配置方法:

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

我应该如何从JWT Cookie验证我的用户?

解答:

如果计划使用HttpContext,则不能在控制器中使用async void方法。HttpContext不是thread安全的,而且由于您返回一个void,所以控制器在返回和处理HttpContext之前不会等待您的登录完成。

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

Async void的意思是“启动并忘记”,并且您不关心之后会发生什么。在本例中,您依赖于异步方法等待后发生的情况,因此需要将其更改为异步任务。

另外,我想说的是,你几乎从不在乎发生了什么,除非你有很强的理由这么做,否则不要使用async void方法。

Change this:

private async void Authenticate(string token)

To this:

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

JWT可以使用User.Identity.IsAuthenticated来验证是否登录了~~~~但是必须经历一个完整的页面请求过程。https://www.cnblogs.com/zhan520g/p/11310738.html

来自:https://www.5axxw.com/questions/content/umjhfd