JWT 令牌验证返回 null。
首先,我生成令牌,并尝试使用授权处理程序对其进行验证,但在处理需求异步函数中,所有声明均为空。
这是生成token的方法:
[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" });
});
}
请告诉我我的代码有什么问题。
您可以尝试使用此代码来让用户摆脱索赔
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;
}
您应该检查您的令牌权限我用这种方式解决我的问题:
services
.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.Authority = authority;
o.TokenValidationParameters.ValidateAudience = false;
o.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
o.RequireHttpsMetadata = requireHttps;
o.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var claims = context.Principal.Identity as ClaimsIdentity;
if (!claims.Claims.Any())
context.Fail("This token has no claims.");
return Task.CompletedTask;
},
OnChallenge = context =>
{
if (context.AuthenticateFailure != null)
throw new AppException("Authenticate failure.", HttpStatusCode.Unauthorized);
throw new AppException("You are unauthorized to access this resource.", HttpStatusCode.Unauthorized);
}
};
});