如何解决如何从 .net core 中的 jwt 令牌中获取用户的 id 或如何从自定义授权属性返回值?
我通过以下方式创建我的令牌
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name,user.Id.ToString()),new Claim(ClaimTypes.Role,"tada")
}),Expires = DateTime.UtcNow.AddDays(7),SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.Createtoken(tokenDescriptor);
var encryptedtoken = tokenHandler.Writetoken(token);
现在我想简单地从我的授权属性中获取用户 ID 并以某种方式将其放入上下文中? 我知道我可以像这样解码令牌
[Authorize(Roles = "tada")]
public IActionResult Get()
{
var token = HttpContext.Request.Headers[HeaderNames.Authorization][0];
var tokenArray = token.Split(" ");
var handler = new JwtSecurityTokenHandler();
var tokenS = handler.ReadToken(tokenArray[1]) as JwtSecurityToken;
return Ok(tokenS.Payload.SingleOrDefault(t => t.Key == "unique_name").Value);
}
但是我如何以更聪明的方式重用这段代码,我可以创建自己的授权属性,如果没有办法将其存储在上下文中,我如何创建单例/范围/瞬态服务?
这是我如何配置 jwt
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CatstagramDbContext>(options =>
options.UsesqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddIdentity<User,IdentityRole>(options =>
{
options.Password.requiredigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.requiredLength = 6;
})
.AddEntityFrameworkStores<CatstagramDbContext>();
var applicationSettingConfiguration = Configuration.GetSection("ApplicationSettings");
services.Configure<AppSettings>(applicationSettingConfiguration);
var appSettings = applicationSettingConfiguration.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.Savetoken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(key),ValidateIssuer = false,ValidateAudience = false
};
});
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.ApplyMigrations();
}
}
解决方法
我正在使用此函数获取任何令牌声明值
public static string GetClaimValue(HttpContext httpContext,string valueType)
{
if (string.IsNullOrEmpty(valueType)) return null;
var identity = httpContext.User.Identity as ClaimsIdentity;
var valueObj = identity == null ? null : identity.Claims.FirstOrDefault(x => x.Type == valueType);
return valueObj==null? null:valueObj.Value;
}
你可以这样使用它
var name = GetClaimValue(HttpContext,"unique_name");
,
当身份验证中间件对请求进行身份验证时,它会使用保存当前用户声明的 HttpContext.User
填充 ClaimsPrincipal
属性。
ClaimsPrincipal
类在名为 System.Security.Claims
的命名空间中的 FindFirstValue
中有一个扩展方法。
User.FindFirstValue("unique_name");
为您提供第一个 unique_name
声明的值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。