我正在使用ASP.NET7框架制作我的第一个API.我正在使用JWT令牌.我有一个问题,Authorize标签总是返回UnAuthorize.我已经判断了来自客户端的正确访问令牌,唯一的问题是标签无法验证它.我附上了我的巴新项目的 struct .以下是My Program.cs的代码


using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;


using WebApi.Models;
using WebApi.Services;
using WebApi;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();

builder.Services.AddDbContext<UserContext>(opt =>
    opt.UseInMemoryDatabase("UserList"));

builder.Services.AddScoped<ITokenService, TokenService>();

builder.Services.AddSingleton<IPasswordHasher, PasswordHasher>();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddAuthorization();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new TokenValidationParameters {
            
            ValidateIssuer = true,
            
            ValidIssuer = AuthOptions.ISSUER,
            
            ValidateAudience = true,
            
            ValidAudience = AuthOptions.AUDIENCE,
            
            ValidateLifetime = true, //make true after tests
            
            IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
            
            ValidateIssuerSigningKey = true,
        };
        
        
    });

WebApplication app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}

//app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();



app.Run();

现在我的 token 一代:

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;


using System.Text;


namespace WebApi.Services {
    
    public class TokenService : ITokenService {

        public string GenerateAccessToken(string username) {

            List<Claim> claims = new() {
                new Claim(ClaimTypes.Name, username)
            };

            SymmetricSecurityKey key = new(Encoding.UTF8.GetBytes(AuthOptions.SECRETKEY));
            SigningCredentials creds = new(key, Security算法rithms.HmacSha256);

            
            JwtSecurityToken token = new(
                issuer: AuthOptions.ISSUER,
                audience: AuthOptions.AUDIENCE,
                claims: claims,
                expires: DateTime.UtcNow.AddMinutes(AuthOptions.ACCESSTOKENLIFETIME),
                signingCredentials: creds
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
            

        }
}

以及我正在try 使用[授权]的控制器中的位置

[HttpGet("{id}")]
[Authorize]
public async Task<IActionResult> GetUserById(int id) {

    
    string username = HttpContext.User.Identity.Name;

    string token = HttpContext.Request.Headers["Authorization"].FirstOrDefault()?.Replace("Bearer ", "");

    _logger.LogInformation(username + " username");
    _logger.LogInformation(token + " token");

    User? user = await _dbContext.Users.FirstOrDefaultAsync(u => u.email == username);

    

    if (user == null) {
        return NotFound("User not found");
    }

    int userId = user.id;

    if (userId != id) {
        return Unauthorized("Unauthorized");
    }

    string newAccessToken = _tokenService.GenerateAccessToken(user.username);

    UserInfoResponse userInfo = new() {

        username = user.username,
        id = user.id,
        avatar = user.avatar,
        accessToken = newAccessToken
    };

    return Ok(userInfo);
    
}

enter image description here

我try 在Program.cs中注释掉HTTPS强制(app.UseHttpsReDirection();),但没有帮助

推荐答案

您正在判断基于HttpContext.User.Identity.Name的访问权限,但是您正在添加用户名作为声明.

try 判断用户名,如下所示:

string username = context.User.Claims.Where(c => c.Type == ClaimTypes.Name).Select(a => a.Value.ToString()).FirstOrDefault();

还可以判断this answer中的ClaimsPrincipalExtensions个例子

Csharp相关问答推荐

亚马逊Pinpoint C# SDK

当我使用NET6作为目标框架时,为什么DotNet使用NET8作为MS包?

需要在重新启动ApplicartionPool或IIS后启动/唤醒API的帮助

如何将不同类型的扩展参数的javascript函数转换成C#风格?

C#EF Core WHERE IN LINQ FROM LIST WITH.CONTAINS不返回任何内容

单元测试:模拟返回空

在C#中反序列化/序列化具有混合元素顺序的XML时出现问题

.NET 8 DI GetServices<;对象&>不工作

自定义列表按字符串的部分排序

避免只读记录 struct 中的防御副本

.NET 6:如何防止系统生成的日志(log)?

C#多键字典和TryGetValue

在.NET8中如何反序列化为私有字段?

工厂类是如何在.NET 8中注册的?

如何在C# WinForm控件中使用Windows 10/11的黑暗主题?

Azure队列触发器未使用隔离的工作进程执行

将列表转换为带有逗号分隔字符串形式的值的字典

单位中快照的倾斜方向

我想我必须手动使用res1(字符串形式的PowerShell哈希表)

根据运行时值获取泛型类型的字典