gpt4 book ai didi

c# - 如何从 Active Directory 获取正确的数据以进行身份​​验证

转载 作者:行者123 更新时间:2023-11-30 18:04:48 24 4
gpt4 key购买 nike

我有一个客户端服务解决方案,其中包含一个 Winforms 客户端应用程序和一个托管在 IIS 中的 WCF 服务。

在 WCF 服务中,我可以使用自定义 IAuthorizationPolicy 轻松提取在客户端登录的当前用户名 (WindowsIdentity.Name)。这是通过从 Evaluate 方法中传入的 EvaluationContext 获取 WindowsIdentity 来完成的。

WindowsIdentity.Name 看起来像这样:MyCompanyGroup\MyName

为了能够在我自己的成员资格模型中绑定(bind)到 AD 帐户,我需要能够让用户在 Winforms 客户端上选择要绑定(bind)到的 AD 用户。要为树提取 AD 组和用户,我使用以下代码:

public static class ActiveDirectoryHandler
{
public static List<ActiveDirectoryTreeNode> GetGroups()
{
DirectoryEntry objADAM = default(DirectoryEntry);
// Binding object.
DirectoryEntry objGroupEntry = default(DirectoryEntry);
// Group Results.
DirectorySearcher objSearchADAM = default(DirectorySearcher);
// Search object.
SearchResultCollection objSearchResults = default(SearchResultCollection);
// Results collection.
string strPath = null;
// Binding path.
List<ActiveDirectoryTreeNode> result = new List<ActiveDirectoryTreeNode>();

// Construct the binding string.
strPath = "LDAP://stefanserver.stefannet.local";
//Change to your ADserver

// Get the AD LDS object.
try
{
objADAM = new DirectoryEntry();//strPath);
objADAM.RefreshCache();
}
catch (Exception e)
{
throw e;
}

// Get search object, specify filter and scope,
// perform search.
try
{
objSearchADAM = new DirectorySearcher(objADAM);
objSearchADAM.Filter = "(&(objectClass=group))";
objSearchADAM.SearchScope = SearchScope.Subtree;
objSearchResults = objSearchADAM.FindAll();
}
catch (Exception e)
{
throw e;
}

// Enumerate groups
try
{
if (objSearchResults.Count != 0)
{
//SearchResult objResult = default(SearchResult);
foreach (SearchResult objResult in objSearchResults)
{
objGroupEntry = objResult.GetDirectoryEntry();
result.Add(new ActiveDirectoryTreeNode() { Id = objGroupEntry.Guid, ParentId = objGroupEntry.Parent.Guid, Text = objGroupEntry.Name, Type = ActiveDirectoryType.Group, PickableNode = false });

foreach (object child in objGroupEntry.Properties["member"])
result.Add(new ActiveDirectoryTreeNode() { Id= Guid.NewGuid(), ParentId = objGroupEntry.Guid, Text = child.ToString(), Type = ActiveDirectoryType.User, PickableNode = true });
}
}
else
{
throw new Exception("No groups found");
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}

return result;
}
}

public class ActiveDirectoryTreeNode : ISearchable
{
private Boolean _pickableNode = false;
#region Properties
[GenericTreeColumn(GenericTableDescriptionAttribute.MemberTypeEnum.TextBox, 0, VisibleInListMode = false, Editable = false)]
public Guid Id { get; set; }
[GenericTreeColumn(GenericTableDescriptionAttribute.MemberTypeEnum.TextBox, 1, VisibleInListMode = false, Editable = false)]
public Guid ParentId { get; set; }
[GenericTreeColumn(GenericTableDescriptionAttribute.MemberTypeEnum.TextBox, 2, Editable = false)]
public string Text { get; set; }
public ActiveDirectoryType Type { get; set; }
#endregion

#region ISearchable
public string SearchString
{
get { return Text.ToLower(); }
}

public bool PickableNode
{
get { return _pickableNode; }
set { _pickableNode = value; }
}
#endregion

}

public enum ActiveDirectoryType
{
Group,
User
}

这棵树可能看起来像这样:

CN=Users*
- CN=Domain Guests,CN=Users,DC=MyCompany,DC=local
- CN=5-1-5-11,CN=ForeignSecurityPrinipals,DC=MyCompany,DC=local
...
CN=Domain Admins
- CN=MyName,CN=Users,DC=MyCompany,DC=local
...

(* = 组)

名称的格式不同,我看不出这与服务上的名称有什么区别。

那么如何为树提取正确的 Active Directory 数据?

最佳答案

我不能说我明白你在问什么,但这里有一些信息,希望你能找到帮助。

您在服务中看到的登录名(即“MyName”)对应于 AD 中名为 sAMAccountName 的属性。您可以从 DirectoryEntry 中提取 sAMAccountName通过Properties收藏。例如,如果您想要显示组中每个成员的 sAMAccountName,您可以执行以下操作:

var objSearchADAM = new DirectorySearcher();
objSearchADAM.Filter = "(&(objectClass=group))";
objSearchADAM.SearchScope = SearchScope.Subtree;
var objSearchResults = objSearchADAM.FindAll();

foreach (SearchResult objResult in objSearchResults)
{
using (var objGroupEntry = objResult.GetDirectoryEntry())
{
foreach (string child in objGroupEntry.Properties["member"])
{
var path = "LDAP://" + child.Replace("/", "\\/");
using (var memberEntry = new DirectoryEntry(path))
{
if (memberEntry.Properties.Contains("sAMAccountName"))
{
// Get sAMAccountName
string sAMAccountName = memberEntry.Properties["sAMAccountName"][0].ToString();
Console.WriteLine(sAMAccountName);
}

if (memberEntry.Properties.Contains("objectSid"))
{
// Get objectSid
byte[] sidBytes = (byte[]) memberEntry.Properties["objectSid"][0];
var sid = new System.Security.Principal.SecurityIdentifier(sidBytes, 0);
Console.WriteLine(sid.ToString());
}
}
}
}
}

您可能还会找到 UserPrincipal有趣的。使用此类,您可以使用 FindByIdentity 非常轻松地连接到 AD 中的用户对象。方法如下图:

var ctx = new PrincipalContext(ContextType.Domain, null);
using (var up = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "MyName"))
{
Console.WriteLine(up.DistinguishedName);
Console.WriteLine(up.SamAccountName);

// Print groups that this user is a member of
foreach (var group in up.GetGroups())
{
Console.WriteLine(group.SamAccountName);
}
}

关于c# - 如何从 Active Directory 获取正确的数据以进行身份​​验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6042800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com