令牌是通过以下方法生成的:

private string GenerateJwtToken(User user)
{
    var tokenHandler = new JwtSecurityTokenHandler();

    var base64Key = _configuration["Jwt:Secret"];

    try
    {
        var key = Convert.FromBase64String(base64Key);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Issuer = _configuration["Jwt:Issuer"],
            Audience = _configuration["Jwt:Audience"],
            Subject = new ClaimsIdentity(
                new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.Email),
                    new Claim("UserId", user.ID.ToString())
                }
            ),
            Expires = DateTime.UtcNow.AddDays(14),
            SigningCredentials = new SigningCredentials(
                new SymmetricSecurityKey(key),
                Security算法rithms.HmacSha256Signature
            )
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }
    catch (FormatException ex)
    {
        Console.WriteLine($"error converting Base64 string: {ex.Message}");
        return null;
    }
}

我在jwt.io上判断了一下,它说生成的令牌是有效的.

当我使用thunderclient到我的/user端点,通过在头中传递JWT令牌来获取用户时,我会得到Status:401 Unauthorized.

下面是我的POST方法:

[HttpPost]
[Authorize]
public async Task<ActionResult<UserDTO>> GetUserDTO()
{
    Console.WriteLine("I GET USER");
    try
    {
        var jwt = HttpContext.Request.Headers["Authorization"]
                .ToString()
                .Replace("Bearer ", string.Empty);

        Console.WriteLine(jwt);
        if (string.IsNullOrWhiteSpace(jwt))
        {
            return BadRequest("JWT token is missing.");
        }
        var loggedInUser = _userService.GetByJWT(jwt);

        if (loggedInUser == null)
        {
            return BadRequest("Failed to get user.");
        }

        return Ok(loggedInUser.FirstName);
    }
    catch (Exception e)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
    }
}

当我go 掉[Authorize]时,它就可以工作了,它可以从JWT载体中解析ID.

program.cs中,我有我的授权模式,并试图更改它,看看它是否与我的发行者或受众有问题?我将我的发行者值设置为我的应用程序名称,将受众值设置为API,因为它是将使用它的API.对吗?以下是模式:

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"])
            ),
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"]
        };
    });

builder.Services.AddAuthorization();

为什么我得到了未经授权的?

100 下面是我try 设置标题/授权的方法

enter image description here

enter image description here

推荐答案

问题是你使用了两个不同的键,请参阅以下几行:

var key = Convert.FromBase64String(base64Key); //used to generate a jwt

IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"])
            ) // used to check a jwt

基本上,对于相同的字符串,Encoding.UTF8.GetBytesConvert.FromBase64String(base64Key)不会返回相同的byte[]

在您的.AddJwtBearer方法调用中将该行更改为以下行

IssuerSigningKey = new SymmetricSecurityKey(
                Convert.FromBase64String(builder.Configuration["Jwt:Secret"])
            ) // used to check a jwt

Csharp相关问答推荐

.NET最小API映射将T参数列表为[FromQuery]

System.Text.Json数据化的C#类映射

C++/C#HostFXR通过std::tuple传递参数

图形API基于appid列表检索多个应用程序

如何删除文件的基础上嵌入的时间戳嵌入文件名

在路由中使用枚举

如何解决提交按钮后 Select 选项错误空参照异常

如何使用C#获取FireStore中的列表输出文档

从VS调试器而不是测试资源管理器运行的调试NUnitDotNet测试

将类移动到新命名空间后更新RavenDB Raven-Clr-Type

如何向事件添加成员

如何在不复制或使用输出的情况下定义项目依赖

在使用StringBuilder时,如何根据 colored颜色 设置为richTextBox中的特定行着色?

数据库.Migrate在对接容器重启时失败

使用CollectionView时在.NET Maui中显示数据时出现问题

获取混淆&Quot;模糊引用&Quot;错误

Blazor:搜索框在第一次搜索时不搜索

使用DI实例化带有动态参数的服务?

根据优先级整理合同列表

try 访问字典中的模拟对象时引发KeyNotFoundException