我有一个使用 Windows 身份验证的 ASP.Net MVC 应用程序,我正在检查组成员身份以确保 Controller 操作的安全性。
听起来很简单,但我发现没有其他问题可以解决我遇到的问题。
第一次尝试:[授权]
经典的方法是简单地在 Controller 操作上添加一个Authorize
数据注释属性然后去镇上:
[Authorize(Roles = @"domain\groupName1")]
没有骰子。系统提示我输入凭据。通常这意味着 Windows 身份验证配置有问题,但设置正常:(1) HttpContext.User
是一个 WindowsPrincipal
对象,并且 (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。
第三次尝试:搜索身份的群组集合
在我的 Controller 中,我检查了 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
对象,其 SID 与HttpContext
上的当前 WindowsPrincipal
。
问题:
我到底错过了什么?当通过对象探索清楚地表明用户是该给定组的有效成员时,为什么两种角色检查方法都会失败?
在这一点上,一组检查正常而另一组检查似乎不是最奇怪的部分。
最佳答案
回答:
本质上是 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
(AD 条目中的“SamAccountName”)实例化 NTAccount
。
这解释了上面 #1 和 #2 中的失败。
要授权 HttpContext.User
除了他/她的 Sid 或 SamAccountName,您需要 DirectoryServices.AccountManagement
或经典 LDAP。
关于c# - .Net 4.5 中的 Active Directory 组成员身份检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13147132/