Active Directory组成员资格检查.Net 4.5
我有一个使用Windows身份验证的ASP.Net MVC应用程序,并且我正在检查组成员身份以确定控制器操作的安全性。
听起来很简单,我发现没有其他问题可以解决我遇到的问题。
第一次尝试:[授权]
经典的方法是简单地掌握控制器操作上的Authorize
数据注释属性并转到镇上:
[Authorize(Roles = @"domaingroupName1")]
没有骰子。 我被提示输入凭据。 通常,这意味着Windows身份验证配置有问题,但设置正确:(1) HttpContext.User
是WindowsPrincipal
对象,(2)我确认了另一个已知的组名。
第二次尝试:IsInRole()
采取下一步是去一个更老式的路线和使用IPrincipal.IsInRole()
并再次,一个返回false
,其他的true
。
var wp = (WindowsPrincipal)User;
// false
var inGroup1 = wp.IsInRole(@"domaingroupName1");
// true
var inGroup2 = wp.IsInRole(@"domaingroupName2");
难倒了...所以我打了我的系统书呆子,我们仔细检查一切。 用户是群组成员? 是。 组名拼写正确吗? 是。 下一步是阻止SID。
第三次尝试:搜索身份的群集
在我的控制器中,我检查WindowsIdentity
并查看组合集合中的麻烦组的SID:
var wi = (WindowsIdentity)wp.Identity;
var group = wi.Groups.SingleOrDefault(g => g.Value == "group1-sidValue");
group
变量是SecurityIdentifier
对象。 因为它不为空,所以我们可以确定,当前用户是[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
对象,它具有与HttpContext
上的当前WindowsPrincipal
相同的SID。
题:
我到底在想什么? 为什么两个角色检查方法学在通过对象探索明确而清楚地知道用户是这个给定组的有效成员时会失败?
事实上,一个小组检查罚款,另一个似乎并没有在这一点上最奇怪的部分。
回答:
本质上它是WindowsIdentity
和NTAccount
(这两个System.Security.Principal)之间的翻译问题,最后是实际的Active Directory条目。
当针对AD验证WindowsIdentity
时,如果您想使用除Sam或Sid以外的其他任何内容,则需要使用System.DirectoryServices.AccountManagement
。
警告:在.Net 4.5中,安全主体包含索赔,但这与上下文无关。
长解释:
在Windows身份验证的Web应用程序中, HttpContext.User
是包装基础WindowsIdentity
的WindowsPrincipal
对象。
WindowsIdentity
对于大多数意图和目的只有两个属性,可以识别经过身份验证的用户: Name
和User
。
这些属性转换为身份的相应AD帐户条目的两个属性:
WindowsIdentity.Name
= SamAccountName
WindowsIdentity.User
= SID
[Authorize]
过滤器属性最终调用底层主体上的IsInRole(string role)
,并且IsInRole()
字符串重载实例化具有该role
的NTAccount
(AD条目中的“SamAccountName”)。
这解释了上面#1和#2中的失败。
要授权HttpContext.User
除了他/她的Sid或SamAccountName之外的任何内容,您需要使用DirectoryServices.AccountManagement
或传统的LDAP。
我有一个使用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_nameyour_group_name", StringComparison.InvariantCultureIgnoreCase))
{
// the user belongs to a group
}
}
这就是我在Web.config文件中<authentication mode="Windows"/>
旁边所需的全部内容