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

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相关问答推荐

当前的文化决定了错误的文化

如何在我的C#应用程序中设置带有reactjs前端的SignalR服务器?

Regex字母数字校验

当我将`ConcurentDictionary`转换为`IDictionary`时,出现了奇怪的并发行为

KeyDown从我的文本框中删除输入,如何停止?

C#静态抽象属性不能被子接口覆盖

try 创建一个C#程序,该程序使用自动实现的属性、覆盖ToString()并使用子类

如何在单击按钮后多次异步更新标签

与另一个对象位于同一位置的对象具有不同的变换位置

我什么时候不应该在Dispose中调用EgSuppressFinalize(This)?

如何模拟一个返回OneOf IServiceA,IServiceB的方法?使用Moq

在Word Open OpenXML c#上应用葡萄牙语字符Times New Roman时出错

为什么在Web服务中使用异步(&Q)

如何显示;CA1806:不要忽视方法结果;对于不可变列表<;T>;.添加

异步实现上的C#同步

";如何在C#中基于多个属性有效地对自定义对象列表进行排序?

如何在.NET Core 7中更改Antiforgery cookie路径

标签字体不';在maui中使用TemplateBinding时不适用

基于一个字段识别大文件中的重复项并删除记录

通过将静态字段作为方法参数传递来更新静态字段