在我的asp.net core 2.0网络应用程序中,我有一个ISecurityTokenValidator用于验证令牌的自定义。
它依赖于存储库来执行db查找-存储库本身被设置为作用域依赖项:
services.AddScoped<IMyRepository>(MyRepository);
Run Code Online (Sandbox Code Playgroud)
现在,由于ISecurityTokenValidator的设置方式而变得有趣。
它添加在ConfigureServices:
.AddJwtBearer(options =>
{
options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new MyTokenValidator(services.BuildServiceProvider()));
})
Run Code Online (Sandbox Code Playgroud)
它是这样的:
public class MyTokenValidator : ISecurityTokenValidator
{
private readonly IServiceProvider _serviceProvider;
public MyTokenValidator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public bool CanReadToken(string securityToken) => true;
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters,
out SecurityToken validatedToken)
{
var serviceScopeFactory = _serviceProvider.GetRequiredService<IServiceScopeFactory>();
using (var scope = serviceScopeFactory.CreateScope())
{
var myRepository = scope.ServiceProvider.GetService<IMyRepository>();
var principalFactory = scope.ServiceProvider.GetService<IUserClaimsPrincipalFactory<User>>();
// Use the repo....
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,由于IsecurityTokenProvider仅实例化一次,因此实际上是单例。当我使用服务提供商提出要求时,IMyRepository我发现我总是收到相同的对象-就它而言,没有新的作用域,因为它在单例类中。
为了解决这个问题,您将在上面的代码中看到,每次调用令牌验证器时,Ive必须手动强制使用新作用域。这真的是解决此问题的唯一方法,似乎我正在四处寻找使其在这里工作...
her*_*ist 19
老问题,但我发现解决这个问题的最好方法是使用IPostConfigureOptions<JwtBearerOptions>配置 SecurityTokenValidators。
首先注册JWT承载和选项
services.AddAuthentication(options =>
{
...
}).AddJwtBearer(AuthenticateScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
...
};
});
Run Code Online (Sandbox Code Playgroud)
然后注册一个自定义实现 IPostConfigureOptions<JwtBearerOptions>
services.AddSingleton<IPostConfigureOptions<JwtBearerOptions>, CustomJwtBearerOptionsPostConfigureOptions>();
Run Code Online (Sandbox Code Playgroud)
并注册一个自定义实现 ISecurityTokenValidator
services.AddSingleton<MyCustomSecurityTokenValidator>();
Run Code Online (Sandbox Code Playgroud)
CustomJwtBearerOptionsPostConfigureOptions 可能类似于:
public class CustomJwtBearerOptionsPostConfigureOptions : IPostConfigureOptions<JwtBearerOptions>
{
private readonly MyCustomSecurityTokenValidator _tokenValidator; //example dependancy
public CustomJwtBearerOptionsPostConfigureOptions(MyCustomSecurityTokenValidator tokenValidator)
{
_tokenValidator = tokenValidator;
}
public void PostConfigure(string name, JwtBearerOptions options)
{
options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(_tokenValidator);
}
}
Run Code Online (Sandbox Code Playgroud)
现在 options.SecurityTokenValidators 由CustomJwtBearerOptionsPostConfigureOptions它配置,通过依赖注入实例化并且可以传递相关的规范。
| 归档时间: |
|
| 查看次数: |
950 次 |
| 最近记录: |