在 ASP.NET MVC 5 中向 windows 角色添加自定义角色
Adding custom roles to windows roles in ASP.NET MVC 5
我正在使用 ASP.NET MVC 5 构建 Intranet 应用程序。
我的目标是让 Active Directory 对任何用户进行身份验证(即我正在使用 "Windows Authentication"),然后将组添加到应用程序内的任何用户(不使用域组)。
我在这里发现了一些非常有趣的代码:
http://brockallen.com/2013/01/17/adding-custom-roles-to-windows-roles-in-asp-net-using-claims/
但它在我的场景中不起作用:当我用 [Authorize(Role="AppRole")] 装饰控制器时,即使用户(使用 Claims)与"AppRole" 角色。
这是我的代码:
在Global.asax.cs
void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
string[] roles = Utils.GetRolesForUser(User.Identity.Name);
var id = ClaimsPrincipal.Current.Identities.First();
foreach (var role in roles)
{
//id.AddClaim(new Claim(ClaimTypes.Role, role.ToString()));
id.AddClaim(new Claim(ClaimTypes.Role, @"Kairos.mil\Compliance"));
}
bool pippo = User.IsInRole("Compliance");
HttpContext.Current.User = (IPrincipal)id ;
bool pippo2 = User.IsInRole("Compliance");
}
}
GetRolesForUser 函数如下(运行正常):
public static string[] GetRolesForUser(string username)
{
dbOrdiniPersonaliEntities db = new dbOrdiniPersonaliEntities();
string utente = StripDomain(username);
string[] gruppi = new string[db.vGruppiUtentis.Where(t => t.KairosLogin == utente).Count()];
int i=0;
foreach (var gruppo in db.vGruppiUtentis.Where(t => t.KairosLogin == utente))
{
gruppi[i]=gruppo.GruppoDes;
i=i++;
}
return gruppi;
}
并且控制器装饰有 "standard" 授权子句:
[Authorize(Roles="AppRole")]
public ActionResult Index(string sortOrder, string currentFilter, string DesSearchString,int? page)
{
// my code here
}
有什么想法吗?
提前致谢
更新
谢谢@Leandro
我试过你建议的以下代码
void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
string[] roles = Utils.GetRolesForUser(User.Identity.Name);
ClaimsIdentity id = ClaimsPrincipal.Current.Identities.First();
foreach (var role in roles)
{
//id.AddClaim(new Claim(ClaimTypes.Role, role.ToString()));
id.AddClaim(new Claim(ClaimTypes.Role, @"Kairos.mil\Compliance"));
}
bool pippo = User.IsInRole("Compliance");
SetPrincipal((IPrincipal)id);
bool pippo2 = User.IsInRole("Compliance");
}
}
但是当代码到达这一点时,我收到 运行 次错误
SetPrincipal((IPrincipal)id);
错误如下
无法将类型 'System.Security.Principal.WindowsIdentity' 的对象转换为类型 'System.Security.Principal.IPrincipal'。
感谢您的帮助
更新 2(可能已解决)
你好
深入研究 SO,我发现了这个资源
ASP.NET MVC and Windows Authentication with custom roles
根据@Xhalent的回答,我修改了我的代码如下
protected void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
String[] roles = Utils.GetRolesForUser(User.Identity.Name);
GenericPrincipal principal = new GenericPrincipal(User.Identity, roles);
Thread.CurrentPrincipal = HttpContext.Current.User = principal;
}
}
现在看来工作正常!任何意见?有什么缺点吗?非常感谢!!
使用这个方法保存主体,所以在线程中也设置:
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
更新:还允许匿名并测试 User.IsInRole 是否在方法中获取某些内容。
我正在使用 ASP.NET MVC 5 构建 Intranet 应用程序。
我的目标是让 Active Directory 对任何用户进行身份验证(即我正在使用 "Windows Authentication"),然后将组添加到应用程序内的任何用户(不使用域组)。
我在这里发现了一些非常有趣的代码:
http://brockallen.com/2013/01/17/adding-custom-roles-to-windows-roles-in-asp-net-using-claims/
但它在我的场景中不起作用:当我用 [Authorize(Role="AppRole")] 装饰控制器时,即使用户(使用 Claims)与"AppRole" 角色。
这是我的代码:
在Global.asax.cs
void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
string[] roles = Utils.GetRolesForUser(User.Identity.Name);
var id = ClaimsPrincipal.Current.Identities.First();
foreach (var role in roles)
{
//id.AddClaim(new Claim(ClaimTypes.Role, role.ToString()));
id.AddClaim(new Claim(ClaimTypes.Role, @"Kairos.mil\Compliance"));
}
bool pippo = User.IsInRole("Compliance");
HttpContext.Current.User = (IPrincipal)id ;
bool pippo2 = User.IsInRole("Compliance");
}
}
GetRolesForUser 函数如下(运行正常):
public static string[] GetRolesForUser(string username)
{
dbOrdiniPersonaliEntities db = new dbOrdiniPersonaliEntities();
string utente = StripDomain(username);
string[] gruppi = new string[db.vGruppiUtentis.Where(t => t.KairosLogin == utente).Count()];
int i=0;
foreach (var gruppo in db.vGruppiUtentis.Where(t => t.KairosLogin == utente))
{
gruppi[i]=gruppo.GruppoDes;
i=i++;
}
return gruppi;
}
并且控制器装饰有 "standard" 授权子句:
[Authorize(Roles="AppRole")]
public ActionResult Index(string sortOrder, string currentFilter, string DesSearchString,int? page)
{
// my code here
}
有什么想法吗?
提前致谢
更新
谢谢@Leandro 我试过你建议的以下代码
void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
string[] roles = Utils.GetRolesForUser(User.Identity.Name);
ClaimsIdentity id = ClaimsPrincipal.Current.Identities.First();
foreach (var role in roles)
{
//id.AddClaim(new Claim(ClaimTypes.Role, role.ToString()));
id.AddClaim(new Claim(ClaimTypes.Role, @"Kairos.mil\Compliance"));
}
bool pippo = User.IsInRole("Compliance");
SetPrincipal((IPrincipal)id);
bool pippo2 = User.IsInRole("Compliance");
}
}
但是当代码到达这一点时,我收到 运行 次错误
SetPrincipal((IPrincipal)id);
错误如下
无法将类型 'System.Security.Principal.WindowsIdentity' 的对象转换为类型 'System.Security.Principal.IPrincipal'。
感谢您的帮助
更新 2(可能已解决)
你好 深入研究 SO,我发现了这个资源
ASP.NET MVC and Windows Authentication with custom roles
根据@Xhalent的回答,我修改了我的代码如下
protected void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
String[] roles = Utils.GetRolesForUser(User.Identity.Name);
GenericPrincipal principal = new GenericPrincipal(User.Identity, roles);
Thread.CurrentPrincipal = HttpContext.Current.User = principal;
}
}
现在看来工作正常!任何意见?有什么缺点吗?非常感谢!!
使用这个方法保存主体,所以在线程中也设置:
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
更新:还允许匿名并测试 User.IsInRole 是否在方法中获取某些内容。