c# - .Net 4.5 中的 Active Directory 组成员身份检查

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

我有一个使用 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

问题:

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

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

最佳答案

回答:

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

当根据 AD 验证 WindowsIdentity 时,如果您想使用 Sam 或 Sid 以外的任何东西,您将需要使用 System.DirectoryServices.AccountManagement

警告:在 .Net 4.5 中,安全主体包括声明,但这是断章取义的。


详细说明:

在经过 Windows 身份验证的 Web 应用程序中,HttpContext.User 是一个包含底层 WindowsIdentityWindowsPrincipal 对象。

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

这些属性转换为身份对应的 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/

相关文章:

c# - Websocket 的 ReceiveAsync 方法不等待整个消息

c# - 将集合均匀分布到新数组中

c# - ExecuteNonQuery 返回 1,即使更新语句没有影响任何行

asp.net-mvc - Azure Web 应用程序生命周期

asp.net-mvc - 如何将参数传递给 mvc 4 中的局部 View

c# - 如何在 ActiveMQ 中使用 MaxReconnectAttemps

c# - 检查网页是否在平板电脑上运行

java - 使用IKVM生成dll文件时如何添加对资源文件夹的引用

c# - 在 Perl 中加密文件并在 C# 中解密

asp.net-mvc - asp.net mvc url 操作忽略旧参数值