JWT 令牌未被正确验证

JWT token not being validated correctly

我有一个 ASP.NET 使用 JWT 进行验证的核心 MVC 应用程序

我在启动程序中添加身份验证 class,使用我们的应用程序设置文件中的令牌密码来验证令牌。

services.Configure<ApplicationSettings>(Configuration.GetSection("AppSettings"));

var key = System.Text.Encoding.UTF8
            .GetBytes(Configuration.GetSection("AppSettings:Token").Value);

services.AddAuthentication(x => {
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x => {
    x.RequireHttpsMetadata = false;
    x.SaveToken = false;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = false,
        ValidateAudience = false,
        ClockSkew =  TimeSpan.Zero
    };
});

并添加授权中间件

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseCors("MyPolicy");

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseAuthentication();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

现在,当用户尝试登录以下控制器时,方法是 运行,使用相同的令牌密码生成令牌。

    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] UserForLoginDto userForLoginDto)
    {
        var user = await _userManager.FindByNameAsync(userForLoginDto.Username);

        var result = await _signInManager
            .CheckPasswordSignInAsync(user, userForLoginDto.Password, false);



        if (result.Succeeded)
        {
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim("UserID",user.Id.ToString())
                }),
                Expires = DateTime.UtcNow.AddDays(1),
                SigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8
                    .GetBytes(appSettings.Token)), SecurityAlgorithms.HmacSha256Signature)
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(securityToken);

            return Ok(new { token });
        }

        return Unauthorized();
    }

所以当用户登录时,生成一个令牌并发送回客户端。

此时我希望我可以将 [Authorize] 属性添加到控制器方法,然后 MVC 框架将在 http headers 中查找有效令牌。所以我创建了一个测试控制器方法

[HttpGet]
[Authorize]
public IActionResult Get()
{
    return Ok("Test");
}

并发送与授权 header 设置为 Bearer <Token> 的测试控制器方法相对应的请求,但我仍然收到 401 未经授权。

谁能解释为什么会发生这种情况?如果您需要更多信息,请告诉我。

我认为是使用你的中间件的问题:

        app.UseRouting();

        app.UseAuthorization();

        app.UseAuthentication();

可以通过以下方式尝试:


        app.UseAuthentication();
        app.UseRouting();

        app.UseAuthorization();

因此,首先,我们使用对用户进行身份验证 - 中间件读取令牌并将身份注入 http 上下文