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

前端 未结 3 1986
梦谈多话
梦谈多话 2021-01-31 06:40

I created an asp.net core project in visual studio 2015 with windows authentication. I can\'t figure out how to add roles to the Identity.

I have a table with usernames

相关标签:
3条回答
  • 2021-01-31 06:56

    this is working code that I use to check is a user is in a role \ group, please use it at your leisure

    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;
    
        }
    }
    }
    
    0 讨论(0)
  • 2021-01-31 06:59

    With Windows Authentication the roles come from Active Directory, not a database.

    You could use Claims Transformation to change the inbound identity on every request to pull extra roles from your database.

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

    And then wire it up with

    app.UseClaimsTransformation(new ClaimsTransformationOptions
    {
        Transformer = new ClaimsTransformer()
    });
    

    Note that in the current incarnation there's no DI support, so you'll have to manually pull out your database information from DI if that's where it is.

    0 讨论(0)
  • 2021-01-31 07:10

    For anyone interested, here is a simple example of how you can inject an EF DBContext into a custom ClaimsTransformer and add some custom role claims.

    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);
      }
    }
    
    0 讨论(0)
提交回复
热议问题