【发布时间】:2019-10-10 07:51:01
【问题描述】:
我正在尝试使用 ASP.NET Core 中的 Windows 身份验证来使用基于声明的授权。我有一个设置用户声明的声明转换器。我还将IPrincipal 注入到DbContext 中,这样我就可以在调用SaveChanges() 以记录谁更新了实体时访问当前用户。
在 Startup.cs 中:
services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>()?.HttpContext?.User);
services.AddTransient<IClaimsTransformation, MyClaimsTransformer>();
在 MyDbContext.cs 中:
protected readonly IPrincipal _principal ;
public MyDbContext(DbContextOptions<MyDbContext> options, IPrincipal principal) : base(options)
{
_principal = principal;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
// Do something with Claim value...
await base.SaveChangesAsync(cancellationToken);
}
我添加了一个声明转换器来添加一些声明信息:
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
// Add Claims...
return principal;
}
SaveChangesAsync 在用户中间件中被调用以记录对应用程序的访问。在添加 Claims Transformer 之前,注入到 DbContext 中的 IPrincipal 是 WindowsPrincipal,它包含我需要的 Claims,例如 PrimarySid 等。现在添加转换后,它是 ClaimsPrincipal 但是列表of Claims 现在为空。
通过调试,我可以验证 TransformAsync 在 SaveChangesAsync 之前执行,但是 db 上下文中的构造函数注入发生在转换之前(DbContext 是 Scoped 服务,Claims Transfomer 是瞬态的)。
总结:
- 在添加声明转换器之前,注入的
IPrincipal是一个包含声明列表的WindowsPrincipal。 - 添加 Claims Transformer 后,注入的
IPrincipal是一个带有空声明列表的ClaimsPrincipal。
【问题讨论】:
-
将其添加为范围服务
-
@Nkosi 我已经尝试将其他服务更改为 Scoped,没有区别。
标签: c# asp.net-core dependency-injection