gpt4 book ai didi

c# - 添加 Claims Transformer 后注入(inject)的 IPrincipal Claims 为空

转载 作者:行者123 更新时间:2023-12-05 06:26:20 26 4
gpt4 key购买 nike

我正在尝试在 ASP.NET Core 中使用基于 Windows 身份验证的声明授权。我有一个设置用户声明的声明转换器。我还通过 DbContextIPrincipal 注入(inject)到 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);
}

我添加了一个 Claims Transformer 来添加一些 Claim 信息:

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
// Add Claims...
return principal;
}

SaveChangesAsync 在用户中间件中调用以记录对应用程序的访问。在添加Claims Transformer之前,注入(inject)到DbContext中的IPrincipal是一个WindowsPrincipal,里面包含了我需要的Claims,比如PrimarySid等。现在在添加转换后,它是一个 ClaimsPrincipal 但是声明列表现在是空的。

通过调试,我可以验证 TransformAsyncSaveChangesAsync 之前执行,但是数据库上下文中的构造函数注入(inject)发生在转换之前(DbContext是 Scoped 服务,Claims Transformer 是 transient 的。

总结:

  • 在添加 Claims Transformer 之前,注入(inject)的 IPrincipal 是一个包含已填充声明列表的 WindowsPrincipal
  • 添加声明转换器后,注入(inject)的 IPrincipal 是一个包含空声明列表的 ClaimsPrincipal

最佳答案

尝试通过 DbContext 构造函数注入(inject) IPrincipal 时,我遇到了完全相同的问题。我发现注入(inject)到 DbContext 中的 IPrincipal 尚未被 ClaimsTransformer“转换”。

我已经通过创建 UserResolverService 解决了这个问题。

IUserResolverService.cs

public interface IUserResolverService
{
IPrincipal GetUser();
}

UserResolverService.cs

public class UserResolverService : IUserResolverService
{
private readonly IHttpContextAccessor _context;

public UserResolverService(IHttpContextAccessor context)
{
_context = context;
}

public IPrincipal GetUser()
{
return _context.HttpContext.User;
}
}

MyDbContext.cs

private readonly IUserResolverService _userResolverService;

// Call this whenever you need the IPrincipal object
public IPrincipal User => _userResolverService.GetUser();

public MyDbContext(IUserResolverService userResolverService, DbContextOptions<MyDbContext> options)
: base(options)
{
_userResolverService = userResolverService;
}

启动.cs

services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
services.AddTransient<IUserResolverService, UserResolverService>();

关于c# - 添加 Claims Transformer 后注入(inject)的 IPrincipal Claims 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56280285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com