JWT Web 令牌授权验证不提供声明数据

Posted

技术标签:

【中文标题】JWT Web 令牌授权验证不提供声明数据【英文标题】:JWT web token Authorization validation give no data of claims 【发布时间】:2021-09-25 22:38:24 【问题描述】:

JWT 令牌验证给 null 首先,我生成令牌,蚂蚁尝试使用授权处理程序验证令牌,但在处理要求异步函数中,所有声明均为空。 我在其中生成令牌

[Route("GenrateToken")]
    [HttpPost]
    public async Task<string> GenerateJSONWebTokenAsync(mdlTookenRequest request )
    
        
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
        List<Claim> _claim = new List<Claim>();
        _claim.Add(new Claim("_CustomerId", request.CustomerId.ToString()));
        _claim.Add(new Claim("_UserId", request.UserId.ToString()));
        _claim.Add(new Claim("_CustomerType", ((int)request.customerType).ToString()));
        _claim.Add(new Claim("_Name", request.Name ??""));
        var token = new JwtSecurityToken(_config["Jwt:Issuer"],
            _config["Jwt:audience"],
          _claim,
          expires: DateTime.Now.AddHours(Convert.ToInt32(_config["Jwt:tokenExpireinhour"])),
          signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(token);
         
        
    

但在验证所有声明时给出空值。

public class AccessRightRequirement : IAuthorizationRequirement

    public enmDocumentMaster accessRight;

    public AccessRightRequirement(enmDocumentMaster accessRight)
    
        this.accessRight = accessRight;
    

public class AccessRightHandler: AuthorizationHandler<AccessRightRequirement>

    private readonly ICurrentUsers _currentUser;
    public AccessRightHandler(ICurrentUsers currentUser)
    
        _currentUser = currentUser;
    
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccessRightRequirement requirement)
    
var data=context.User.Claims.FirstOrDefault(c => c.Type == "_UserId")?.Value;
if (data=="1")
           
                context.Succeed(requirement);
            
            return Task.CompletedTask;
        

我的启动配置是这样的。

public void ConfigureServices(IServiceCollection services)
    
        services.AddHttpContextAccessor();
        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddCors(options =>
        
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader());
        );
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
        
            options.TokenValidationParameters = new TokenValidationParameters
            
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])),
            ;
        );
        services.AddAuthorization(options =>
        
            foreach (enmDocumentMaster _enm in Enum.GetValues(typeof(enmDocumentMaster)))
            
                options.AddPolicy(_enm.ToString(), policy => policy.Requirements.Add(new AccessRightRequirement(_enm)));
            

        );
        services.AddScoped<IAuthorizationHandler, AccessRightHandler>();
        
        services.AddDbContext<DBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);
        services.AddScoped<IAccount>(ctx => new Account(ctx.GetRequiredService<DBContext>(), ctx.GetRequiredService<IConfiguration>()));
       services.AddScoped<ICurrentUsers>(ctx => new CurrentUsers( ctx.GetRequiredService<DBContext>()));
        //services.AddScoped<ICurrentUsers>(ctx => new CurrentUsers(ctx.GetRequiredService<IHttpContextAccessor>(), ctx.GetRequiredService<DBContext>()));

        services.AddControllers();
        services.AddSwaggerGen(c =>
        
            c.SwaggerDoc("v1", new OpenApiInfo  Title = "B2BApis", Version = "v1" );
        );

        
    

请告诉我代码有什么问题。

【问题讨论】:

请以文本形式提供您的代码,以便我们进行调试。 请立即查看 【参考方案1】:

您可以尝试使用此代码从声明中获取用户

public int? GetUserId()

            int? userId = null;
            var identity = HttpContext.User.Identity as ClaimsIdentity;
var userIdObj = identity == null ? null : 
identity.Claims.FirstOrDefault(x => x.Type == "_UserId");
            if (userIdObj != null) userId = Convert.ToInt32(userIdObj.Value);
            return userId;

【讨论】:

我也尝试使用 HttpContext 获取数据,但仍然得到空值 @Prabhakar 这意味着你没有使用令牌。能否展示一下您正在调用 API 的代码? 在我已经提到的问题中,我创建了一个 GenrateToken 函数。

以上是关于JWT Web 令牌授权验证不提供声明数据的主要内容,如果未能解决你的问题,请参考以下文章

无法访问 WebApi 授权令牌中的 JWT 声明

用于授权和身份验证的多个 JWT 承载

在ASP.NET Core中轻松使用JwtBeare进行身份验证

如何生成包含一些自定义声明的 JWT 访问令牌?

JWT 令牌身份验证失败并显示消息“PII 已隐藏”

如何让我的 Auth0 权限进入 AWS HTTP API Jwt 授权方的访问令牌的范围声明?