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

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 中将角色添加到 Windows 身份验证【英文标题】:How to add Roles to Windows Authentication in ASP.NET Core 【发布时间】:2017-03-05 13:47:18 【问题描述】:

我在 Visual Studio 2015 中创建了一个带有 Windows 身份验证的 asp.net 核心项目。我不知道如何向身份添加角色。

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

我找不到任何与 Windows 身份验证相关的特定示例,但我已经阅读了文档并通过了this guide。而我还是被困住了。

【问题讨论】:

您能否展示您的代码,包括您的 using 语句。我猜在这个阶段你还没有引用System.DirectoryServices。当您这样做时,您可以相对轻松地获取广告信息 @SimonPrice 我没有代码可以表示抱歉,我放弃了所有尝试,因为它不起作用。但是给你一个想法,这只是一个启用了 Windows 身份验证的新项目,从那里我只是痛苦和失败。我一定会查一下'System.DirectoryServices',还有什么是AD? AD 是 Active Directory。您想要实现的项目的想法是什么? @SimonPrice 如果一家公司雇佣了大约 100 名员工,并且他们负责管理他们的 Windows 帐户(状态/信息/等)。为内部使用的网站/应用程序拥有一个单独的帐户对他们来说是一个糟糕的解决方案。因此,我正在寻找仅使用 Windows 帐户并向它们应用角色是否可行。我可以从他们连接的帐户中获取哪些实际信息。我是网络开发的新手,所以一切仍然很混乱。 来这里和我聊天chat.***.com/rooms/126473/windows-auth 【参考方案1】:

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

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 帐户添加角色? 如果您可以在我昨天晚上 20:00 发送的聊天链接中,那么是的,我可以通过它与您交谈 上面的代码对用户所属的组进行检查,而不是角色。【参考方案2】:

对于任何感兴趣的人,这里有一个简单的示例,说明如何将 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);
  

【讨论】:

现在类型改为IClaimsTransformation。【参考方案3】:

使用 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 中提取数据库信息。

【讨论】:

github上的相关问题-github.com/aspnet/Security/issues/863 @blowdart 这在 .netcore 2.0 中有效吗?我没有找到 UseClaimsTransformation。 看起来这在 2.0.见***.com/questions/45709296/…。

以上是关于如何在 ASP.NET Core 中将角色添加到 Windows 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net core MVC6如何在Identity 3中初始添加角色

在 ASP.NET Core MVC 中将自定义查询参数添加到操作 URL

如何在asp.net core中添加多个身份和多个角色

如何在 ASP.NET Core for JWT 中添加角色策略?

防止 AddRedirectToWwwPermanent() 在 ASP.NET Core 2.1 中将“www”添加到 *.azurewebsites.net 的前面

选择 webApi 模板时如何将 ASP.Net 身份添加到 Asp.Net Core?