在.Net 4.5中检查Active Directory组成员身份

时间:2012-10-30 20:30:56

标签: c# .net asp.net-mvc security active-directory

我有一个使用Windows身份验证的ASP.Net MVC应用程序,我正在检查组成员身份以确保控制器操作的安全性。

听起来很简单,我发现没有其他问题可以解决我遇到的问题。

第一次尝试:[授权]

经典方法是简单地在控制器操作上拍一个Authorize数据注释属性并转到城镇:

[Authorize(Roles = @"domain\groupName1")]

没有骰子。我被提示输入凭据。通常这意味着Windows身份验证配置有问题,但设置正常:(1)HttpContext.UserWindowsPrincipal对象,(2)我确认另一个已知的组名有效。

第二次尝试:IsInRole()

下一步是采用更老式的路线并使用IPrincipal.IsInRole(),然后再返回一个false,另一个true

var wp = (WindowsPrincipal)User;

// false
var inGroup1 = wp.IsInRole(@"domain\groupName1");
// true
var inGroup2 = wp.IsInRole(@"domain\groupName2");

难倒...所以我打了我的系统书呆子,我们仔细检查一切。用户是群组成员?是。组名拼写正确吗?是。下一步是阻止SID。

第三次尝试:搜索身份的群集

在我的控制器中,我检查WindowsIdentity并查看群组中的麻烦组的SID:

var wi = (WindowsIdentity)wp.Identity;
var group = wi.Groups.SingleOrDefault(g => g.Value == "group1-sidValue");

group变量是SecurityIdentifier对象。因为它不是null,我们可以确定当前用户是[Authorize()]IsInRole()尝试无法确认的组的成员。

第四次尝试:DirectoryServices.AccountManagement

此时,我很疯狂并添加了对AccountManagement API的引用。我通过名称和SID搜索GroupPrincipal的域上下文:

   var pc = new PrincipalContext(ContextType.Domain, "domain");
   var gp1byName = GroupPrincipal.FindByIdentity(pc, "groupName1")
   var gp1bySid = GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, "group1-sidValue");

两个组主变量都已成熟,具有相同的对象,并且我通过监视变量验证了主体的Members集合包含与当前UserPrincipal具有相同SID的WindowsPrincipal对象在HttpContext

问题:

我到底错过了什么?当通过对象探索明确且清楚地表明用户是该给定组的有效成员时,为什么两种角色检查方法都会失败?

事实上,一组检查正常,另一组似乎不是最奇怪的部分。

2 个答案:

答案 0 :(得分:4)

答案:

基本上它是WindowsIdentityNTAccount(这两者都是System.Security.Principal)之间的翻译问题,最后是实际的Active Directory条目。

在针对AD验证WindowsIdentity时,如果您想使用Sam或Sid以外的任何内容,则需要使用System.DirectoryServices.AccountManagement

警告:在.Net 4.5中,安全主体包括声明,但这不符合上下文。


长说明:

在Windows经过身份验证的Web应用程序中,HttpContext.User是包裹基础WindowsPrincipal的{​​{1}}对象。

WindowsIdentity对于大多数意图和目的而言,只有两个属性可用于识别经过身份验证的用户:WindowsIdentityName

这些属性转换为身份对应的AD帐户条目中的两个属性:

User = WindowsIdentity.Name

SamAccountName = WindowsIdentity.User

SID过滤器属性最终在底层主体上调用[Authorize] ... IsInRole(string role)字符串重载用IsInRole()实例化NTAccount( AD条目中的“SamAccountName”。

这解释了上面#1和#2的失败。

要对role除了他/她的Sid或SamAccountName之外的任何内容进行授权,您需要HttpContext.User或经典LDAP。

答案 1 :(得分:0)

我有一个使用Windows身份验证的ASP.Net MVC应用程序,我正在检查组成员身份以确保控制器操作的安全性。听起来很简单,我发现没有其他问题可以解决我遇到的问题。 花了我很多时间找东西 http://www.c-sharpcorner.com/uploadfile/scottlysle/test-for-user-group-membership-in-Asp-Net-C-Sharp/

检查用户是否属于AD群组的代码:

foreach (System.Security.Principal.IdentityReference group in System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups)
{
     if (String.Equals(group.Translate(typeof(System.Security.Principal.NTAccount)).ToString(), @"your_domain_name\your_group_name", StringComparison.InvariantCultureIgnoreCase))
     {
         // the user belongs to a group 
     }
}

这就是我在Web.config文件

<authentication mode="Windows"/>旁边所需的全部内容
相关问题