Mar*_*tin 5 c# jwt asp.net-core-5.0
我正在尝试使用 JWT 身份验证创建简单的 API,其中每个用户都有不同的密钥,而不是一个全局密钥。这听起来是个简单的问题,但棘手的问题是如何在 StartUp 中正确获取 UserManager进行验证。
第一个也是显而易见的方法是通过依赖注入,如下所示:
public IConfiguration Configuration { get; }
public UserManager<IdentityUser> UserManager { get; }
public Startup(IConfiguration configuration, UserManager<IdentityUser> userManager)
{
Configuration = configuration;
UserManager = userManager;
}
Run Code Online (Sandbox Code Playgroud)
但这会立即崩溃并出现错误:“ System.InvalidOperationException:'无法解析类型'Microsoft.AspNetCore.Identity.UserManager`1 的服务”
所以第二次尝试是使用 BuildServiceProvider:
public void ConfigureServices(IServiceCollection services)
{
...
UserManager<IdentityUser> userManager = services.BuildServiceProvider().GetService<UserManager<IdentityUser>>();
...
}
Run Code Online (Sandbox Code Playgroud)
这实际上是有效的,但有一个丑陋的警告:“ ASP0000:从应用程序代码调用‘BuildServiceProvider’会导致创建单例服务的附加副本。请考虑替代方案,例如依赖注入服务作为‘配置’的参数。 ”
一段时间后,我想出了第三个最终解决方案:
private IApplicationBuilder _app;
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
_app = app;
}
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication().AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = Configuration["JWT:Issuer"],
ValidAudience = Configuration["JWT:Audience"],
IssuerSigningKeyResolver = (token, securityToken, kid, validationParameters) =>
{
List<SecurityKey> keys = new List<SecurityKey>();
JwtSecurityToken jwtToken = (JwtSecurityToken)securityToken;
Claim claimName = jwtToken.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name);
if (claimName != null)
{
string name = claimName.Value;
using IServiceScope serviceScope = _app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope();
UserManager<IdentityUser> userManager = serviceScope.ServiceProvider.GetService<UserManager<IdentityUser>>();
IdentityUser user = userManager.FindByNameAsync(name).GetAwaiter().GetResult();
if (user != null) keys.Add(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(user.JwtSecret)));
}
return keys;
},
//IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"])),
ClockSkew = TimeSpan.Zero
};
});
}
Run Code Online (Sandbox Code Playgroud)
该解决方案有效,到目前为止没有警告或错误,但它干净吗?我可以改进它还是应该采取我没有想到的不同方法?不要对我这么严厉 - 我对 ASP 来说是个新手;)
如果您到目前为止已经做到了并且/或者会给我任何提示,我将不胜感激。谢谢。
| 归档时间: |
|
| 查看次数: |
635 次 |
| 最近记录: |