在C#中,有没有办法使用DirectoryServices.AccountManagement
库或icky-ugly LDAP在没有的情况下查找Active Directory组SID ?
[Authorize]
属性和基础WindowsPrincipal.IsInRole(string role)
仅针对AD中的samAccountName
进行检查。
这不仅是Microsoft在检查角色时建议避免的遗留标识符:
// It is also better from a performance standpoint than the overload that accepts a string.
// The aformentioned overloads remain in this class since we do not want to introduce a
// breaking change. However, this method should be used in all new applications and we should document this.
public virtual bool IsInRole (SecurityIdentifier sid) {}
但我也无法控制AD,并且无法确保samAccountName与我们要求设置的“用户友好”名称保持同步。这就是问题首先出现的原因,传递了复数(Name)而不是单数(samAccountName)字符串...值不一样。
此外,samAccountName和SID可能会更改 - 例如,如果AD管理员删除帐户并重新创建它,则SID肯定会不同,而samAccountName是人为错误的另一个地方,但它们将始终按要求恢复名称/ UPN值。
最终我想编写一个自己的干净的authorize属性来检查组成员资格,而不必硬编码SAM或SID。
我知道我可以使用DirectoryServices.AccountManagement执行此操作:
// get group principal
var pc = new PrincipalContext(ContextType.Domain, "domainName");
var gp = GroupPrincipal.FindByIdentity(pc, IdentityType.Name, "groupName");
// check if user is in group.
var up = UserPrincipal.Current;
var usersGroups = up.GetGroups();
var inGroup = usersGroups.Contains(gp);
我只是想知道是否有一种更简单,更少依赖,非传统的方式来保持要编程的属性,尽可能精益。
我之前的相关问题: Active Directory Group Membership Checking in .Net 4.5
答案 0 :(得分:5)
您可以非常轻松地完成此操作 - 设置域上下文,查找组,获取Sid
属性 - 如下所示:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find your group - by group name, group DN, SAM Account Name - whatever you like!
// This is **NOT** limited to just SAM AccountName!
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, groupSamAccountName);
if(group != null)
{
// this gives you the variable of type "SecurityIdentifier" to be used in your
// call to "IsInRole" ....
SecurityIdentifier groupSid = group.Sid;
string groupSidSDDL = groupSid.Value;
}
另外:我不理解您对使用samAccountName
的厌恶 - 它是每个群组的强制性和唯一属性 - 因此它是唯一标识您的群组的完美匹配!
您应该查看System.DirectoryServices.AccountManagement
(S.DS.AM)命名空间。在这里阅读所有相关内容:
新的S.DS.AM让您可以轻松地与AD中的用户和群组一起玩!