我有一个使用Windows身份验证的ASP.Net MVC应用程序,我正在检查组成员身份以确保控制器操作的安全性.
听起来很简单,我发现没有其他问题可以解决我遇到的问题.
经典的方法是简单地Authorize在控制器动作上打一个数据注释属性并转到城镇:
[Authorize(Roles = @"domain\groupName1")]
Run Code Online (Sandbox Code Playgroud)
没有骰子.我被提示输入凭据.通常这意味着Windows身份验证配置有问题,但设置正常:(1)HttpContext.User是一个WindowsPrincipal对象,(2)我确认另一个已知的组名有效.
采取的下一步是采用更老式的路线并使用IPrincipal.IsInRole(),再一次,一个返回false,另一个true.
var wp = (WindowsPrincipal)User;
// false
var inGroup1 = wp.IsInRole(@"domain\groupName1");
// true
var inGroup2 = wp.IsInRole(@"domain\groupName2");
Run Code Online (Sandbox Code Playgroud)
难倒...所以我打了我的系统书呆子,我们仔细检查一切.用户是群组成员?是.组名拼写正确吗?是.下一步是阻止SID.
在我的控制器中,我检查WindowsIdentity并查看组集合中的麻烦组的SID:
var wi = (WindowsIdentity)wp.Identity;
var group = wi.Groups.SingleOrDefault(g => g.Value == "group1-sidValue");
Run Code Online (Sandbox Code Playgroud)
的group变量是SecurityIdentifier对象.因为它不是null,所以我们可以确定当前用户是这两个[Authorize()]或两个IsInRole()尝试都无法确认的组的成员.
在这一点上,我疯了,并添加了对AccountManagement API的引用.我在域上下文中搜索GroupPrincipal名称和SID:
var pc = new PrincipalContext(ContextType.Domain, "domain");
var gp1byName = GroupPrincipal.FindByIdentity(pc, …Run Code Online (Sandbox Code Playgroud)