如何在 ASP.NET Core 中向 Windows 身份验证添加角色

How to add Roles to Windows Authentication in ASP.NET Core

我在 visual studio 2015 年使用 windows 身份验证创建了一个 asp.net 核心项目。我不知道如何向身份添加角色。

我有一个 table,其中包含 windows 帐户的用户名。当用户打开网站时,用户将被添加到身份中(我假设会发生这种情况,因为我可以通过 User.Identity.Name 显示用户名)并且我想从另一个 table 中提取角色并分配他们给用户,这可能吗?或者也许有更好的方法来做到这一点? (为什么?,如何?)

我找不到任何与 windows 身份验证相关的具体示例,但我已经阅读了文档并完成了 this guide。而我仍然卡住了。

这是我用来检查用户是否在角色\组中的工作代码,请在闲暇时使用它

using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Security.Principal;

namespace Santander.IsUserInGroupOrRole_cs
{

public class IsUserInRole
{
    public static bool IsInGroup(string groupName)
    {
        var myIdentity = GetUserIdWithDomain();
        var myPrincipal = new WindowsPrincipal(myIdentity);
        return myPrincipal.IsInRole(groupName);
    }

    public bool IsInGroup(List<string> groupNames)
    {
        var myIdentity = GetUserIdWithDomain();
        var myPrincipal = new WindowsPrincipal(myIdentity);

        return groupNames.Any(group => myPrincipal.IsInRole(group));
    }

    public static WindowsIdentity GetUserIdWithDomain()
    {
        var myIdentity = WindowsIdentity.GetCurrent();
        return myIdentity;
    }

    public static string GetUserId()
    {
        var id = GetUserIdWithDomain().Name.Split('\');
        return id[1];
    }

    public static string GetUserDisplayName()
    {
        var id = GetUserIdWithDomain().Name.Split('\');

        var dc = new PrincipalContext(ContextType.Domain, id[0]);
        var adUser = UserPrincipal.FindByIdentity(dc, id[1]);
        return adUser.DisplayName;

    }
}
}

使用 Windows 身份验证,角色来自 Active Directory,而不是数据库。

您可以使用声明转换来更改每个请求的入站身份,以从您的数据库中提取额外的角色。

public class ClaimsTransformer : IClaimsTransformer
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        ((ClaimsIdentity)principal.Identity).AddClaim(
            new Claim("ExampleClaim", "true"));
        return Task.FromResult(principal);
    }
}

然后用

连接起来
app.UseClaimsTransformation(new ClaimsTransformationOptions
{
    Transformer = new ClaimsTransformer()
});

请注意,在当前版本中没有 DI 支持,因此您必须手动从 DI 中提取数据库信息(如果有的话)。

对于任何感兴趣的人,这里有一个简单示例,说明如何将 EF DBContext 注入自定义 ClaimsTransformer 并添加一些自定义角色声明。

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
  services.AddScoped<IClaimsTransformer, MyClaimsTransformer>();

  services.AddMvc();

  services.AddDbContext<MyDbContext>(options => options.UseSqlServer(
      Configuration.GetConnectionString("MyConnStringSetting")
    ));

  (...)
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  app.UseClaimsTransformation(context =>
  {
    var transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>();
    return transformer.TransformAsync(context);
  });

  (...)
}

MyClaimsTransformer.cs

public class MyClaimsTransformer : IClaimsTransformer
{
  private readonly MyDbContext _context;

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

  public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
  {
    var identity = (ClaimsIdentity)context.Principal.Identity;
    var userName = identity.Name;
    var roles = _context.Role.Where(r => r.UserRole.Any(u => u.User.Username == userName)).Select(r => r.Name);
    foreach (var role in roles)
    {
      var claim = new Claim(ClaimTypes.Role, role);
      identity.AddClaim(claim);
    }
    return Task.FromResult(context.Principal);
  }
}