我使用Windows身份验证在visual studio 2015中创建了一个asp.net核心项目。我无法弄清楚如何向Identity添加角色。
我有一个包含Windows帐户用户名的表。当用户打开网站时,用户被添加到身份中(我假设发生了什么,因为我可以通过User.Identity.Name显示用户名)并且我想从另一个表中提取角色并分配他们对用户,这可能吗?或许还有更好的方法吗? (为什么?,怎么样?)
我无法找到与Windows身份验证相关的任何示例特定示例,但我已阅读文档并通过了this guide。而且我还是卡住了。
答案 0 :(得分:9)
使用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中提取数据库信息,如果它在哪里。
答案 1 :(得分:3)
这是我用来检查用户是否在角色\组中的工作代码,请在闲暇时使用
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;
}
}
}
答案 2 :(得分: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);
}
}