gpt4 book ai didi

c# - 将声明转换与 Windows 身份验证结合使用

转载 作者:行者123 更新时间:2023-11-30 18:14:10 25 4
gpt4 key购买 nike

在 ASP.NET Core 2.1 应用程序中使用 Windows 身份验证。在数据库中,我们有一个 User 表,用于存储用户及其 Sid。它与 UserProfile 具有 1-1 关系,其中包含我想用于 claim 的信息。

我为声明转换添加了此服务:

public class UserStatusClaimsTransformation : IClaimsTransformation
{
private readonly MyDbContext _context;

public UserStatusClaimsTransformation(MyDbContext context)
{
_context = context;
}

public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
if (principal.Identity is WindowsIdentity identity)
{
User user = await _context.User
.Include(u => u.UserProfile)
.Where(u => new SecurityIdentifier(u.WindowsSid, 0) == identity.User)
.SingleOrDefaultAsync();

if (user != null)
{
identity.AddClaim(new Claim("Status", user.UserProfile));
}
}

return principal;
}
}

我的问题是,一旦注册此服务,在管道中其他地方访问的 IPrincipal 现在是 ClaimsPrincipal 而不是 WindowsPrincipal。例如,在 MyDbContext 中,我通过 DI 注入(inject) IPrincipal:

public MyDbContext(DbContextOptions<MyDbContext> options, IPrincipal principal) : base(options)
{
_principal = principal;
}

以前,这是一个 WindowsPrincipal,我可以从 _principal.Identity.Name 获取用户名,但在注册我的 Claims Transformer 之后,它是一个 ClaimsPrincipal_principal.Identity.Name 为空。在使用声明转换后,是否有办法将通过 DI 提供的 IPrincipal 保留为 WindowsPrincipal

最佳答案

我使用 ASP.NET MVC Core 2.2,这对您来说可能为时已晚,但也许对其他人会有帮助。然后我开始我的应用程序我没有找到有用的信息,这是我的自定义建议。它有效,您可以使用它:

 public class ClaimsLoader : IClaimsTransformation
{
private IUserrolesRepository repository;
public ClaimsLoader(IUserrolesRepository repo)
{
repository = repo;
}
public bool ifRoleExist(ClaimsPrincipal principal, string value)
{
var ci = (ClaimsIdentity)principal.Identity;
var claim = principal.FindAll(ci.RoleClaimType);
foreach (var c in claim)
{
if (c.Value == value)
return true;
}
return false;
}

public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var ci = (ClaimsIdentity)principal.Identity;
List<Userrole> userroles = await repository.Userroles.Include(u => u.R).Include(u => u.U).Where(u => u.U.Uid==principal.Identity.Name.Substring(10)).ToListAsync();

if (userroles!=null) {

foreach (Userrole ur in userroles)
{
Claim claim = new Claim(ci.RoleClaimType, ur.Rid);
if (!ifRoleExist(principal, ur.Rid))
ci.AddClaim(claim);
}
}
return await Task.FromResult(principal);
}
}

这里我没有使用ApplicationDbContext,而是使用了repository,这是repository接口(interface):

    public interface IUserrolesRepository
{
IQueryable<Userrole> Userroles { get; }

}

和 EFUserRepository 类:

public class EFUserrolesRepository : IUserrolesRepository
{
private ApplicationDbContext context;

public EFUserrolesRepository(ApplicationDbContext ctx)
{
context = ctx;
}

public IQueryable<Userrole> Userroles => context.Userrole;

}

这是我的用户角色类(以防万一有人需要它):

public partial class Userrole
{
public string Rid { get; set; }//pk
public string Uid { get; set; }//pk

public virtual Role R { get; set; }//fk
public virtual User U { get; set; }//fk
}

在 ApplicationDbContext 中我也做了一些改变:

public class ApplicationDbContextFactory
: IDesignTimeDbContextFactory<ApplicationDbContext>
{

public ApplicationDbContext CreateDbContext(string[] args) =>
Program.BuildWebHost(args).Services
.GetRequiredService<ApplicationDbContext>();
}

最后在启动中:

        services.AddSingleton<IClaimsTransformation, ClaimsLoader>();
services.AddTransient<IUserrolesRepository, EFUserrolesRepository>();
services.AddMvc();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);



services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);

Program.cs 文件也改变了:

public class Program
{
public static void Main(string[] args)
{
//CreateWebHostBuilder(args).Build().Run();
BuildWebHost(args).Run();
}

/*public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();*/

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseDefaultServiceProvider(options =>
options.ValidateScopes = false)
.Build();
}

就是这样。它应该工作。

关于c# - 将声明转换与 Windows 身份验证结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50937012/

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