7

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

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

第一次尝试:[授权]

经典的方法是简单地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。

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

在我的控制器中,我检查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 的引用。GroupPrincipal我通过名称和 SID在域上下文中搜索:

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

两个组主体变量都具有相同的对象,并且我通过监视变量验证主体的Members集合包含与当前onUserPrincipal具有相同 SID 的对象。WindowsPrincipalHttpContext

问题:

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

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

4

2 回答 2

5

回答:

本质上它是WindowsIdentityNTAccount(这两个 System.Security.Principal)之间的转换问题,最后是实际的 Active Directory 条目。

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

警告:在 .Net 4.5 中,安全主体包括声明,但这与上下文无关。


长解释:

在 Windows Authenticated Web 应用程序中,HttpContext.User是一个WindowsPrincipal包装底层WindowsIdentity.

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

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

WindowsIdentity.Name=SamAccountName

WindowsIdentity.User=SID

过滤器[Authorize]属性最终调用IsInRole(string role)基础主体......并且IsInRole()字符串重载实例化NTAccount带有role(AD条目中的“SamAccountName”)。

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

要授权HttpContext.User除他/她的 Sid 或 SamAccountName 之外的任何内容,您将需要DirectoryServices.AccountManagement或经典 LDAP。

于 2012-10-31T19:21:31.640 回答
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 
     }
}

这就是我<authentication mode="Windows"/>在 Web.config 文件中所需要的

于 2016-01-21T20:45:28.490 回答