Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从JWT验证用户身份_C#_Asp.net Core_Jwt - Fatal编程技术网

C# 从JWT验证用户身份

C# 从JWT验证用户身份,c#,asp.net-core,jwt,C#,Asp.net Core,Jwt,我有一个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

我有一个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,我会将它发送到上面显示的
antenticate
方法。它允许我避免不断地让我的用户输入他们的凭证,如果他们有JWT Cookie的话。如果httpOnly Cookie“JWT”不存在,他们必须通过登录表单输入凭据

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

System.ObjectDisposedException:“IFeatureCollection已被处置。”

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

配置服务方法:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie("CookieAuthentication", config =>
{
    config.Cookie.Name = "UserLoginCookie";
    config.LoginPath = "/SignIn";
});
app.UseAuthentication();
app.UseAuthorization();
配置方法:

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

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

如果计划使用HttpContext,则不能在控制器中使用异步void方法。HttpContext不是线程安全的,因为您返回了一个void,所以控制器不会在返回和处理HttpContext之前等待您的登录完成

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

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

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

更改此项:

私有异步无效身份验证(字符串令牌)
为此:

专用异步任务身份验证(字符串令牌)
并确保相应地更改控制器方法

有关更多信息,请参见此处: