通过 Active Directory (LDAP) 进行应用程序登录
使用轻量级目录访问协议 (LDAP) 验证客户端
引言
有时,我们需要使用 Active Directory 验证我们的客户端。 在本技巧中,我将使用一种名为轻量级目录访问协议 (LDAP) 的协议来验证用户。 我经常向其他人解释相同的内容,现在我将其制作成一个技巧,以便其他人可以轻松地从 CodeProject 获取它。
背景
让我来解释一下 LDAP。 LDAP 是一种用于通过互联网协议 (IP) 网络访问和维护分布式目录信息服务的应用程序协议。
现在,再次阅读时,一个问题浮出脑海,“什么是 Active Directory?” 它是一种特殊用途的数据库,旨在处理大量的读取和搜索操作,以及显著较少数量的更改和更新。 它还保存当前域或网络中有关用户的信息。
为了从 Active Directory 验证用户,我们需要使用 LDAP。
Using the Code
验证用户
为了从 AD (Active Directory) 验证用户,我们需要拥有 LdapConnection
。 然后,使用 NetworkCredential
类,我们可以轻松验证用户。 我创建了一个示例函数,它将返回 boolean
结果(如果用户凭据与 Active Directory 匹配,则返回 true
,否则返回 false
)。
public static bool fnValidateUser()
{
bool validation;
try
{
LdapConnection lcon = new LdapConnection
(new LdapDirectoryIdentifier((string)null, false, false));
NetworkCredential nc = new NetworkCredential(Environment.UserName,
"MyPassword", Environment.UserDomainName);
lcon.Credential = nc;
lcon.AuthType = AuthType.Negotiate;
// user has authenticated at this point,
// as the credentials were used to login to the dc.
lcon.Bind(nc);
validation = true;
}
catch (LdapException)
{
validation = false;
}
return validation;
}
列出所有用户
如果您想列出当前域中的所有用户,则可以使用 DirectoryEntry
类。 这里有一个例子
public static void fnListAllUser()
{
DirectoryEntry directoryEntry = new DirectoryEntry
("WinNT://" + Environment.UserDomainName);
string userNames = "";
string authenticationType="";
foreach (DirectoryEntry child in directoryEntry.Children)
{
if (child.SchemaClassName == "User")
{
userNames += child.Name +
Environment.NewLine; //Iterates and binds all user using a newline
authenticationType += child.Username + Environment.NewLine;
}
}
Console.WriteLine("************************Users************************");
Console.WriteLine(userNames);
Console.WriteLine("*****************Authentication Type*****************");
Console.WriteLine(authenticationType);
}
如果您想获取用户及其各自的组,则需要使用 PrincipalContext
和 GroupPrincipal
类。 请参阅此示例
public static void fnGetListOfUsers() {
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "USERS");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}",
p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
}
}
}
列出用户的详细信息
此外,如果您想获取特定用户的全部详细信息,则需要使用 PropertyCollection
类。 请参阅此示例
public static void fnImp() {
using (var context = new PrincipalContext(ContextType.Domain, Environment.UserDomainName))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
if ((string)de.Properties["givenName"].Value == Environment.UserName)
{
//Console.WriteLine("First Name: " +
//de.Properties["givenName"].Value);
//Console.WriteLine("Last Name : " +
//de.Properties["sn"].Value);
//Console.WriteLine("SAM account name : " +
//de.Properties["samAccountName"].Value);
//Console.WriteLine("User principal name: " +
//de.Properties["userPrincipalName"].Value);
Console.WriteLine();
PropertyCollection pc = de.Properties;
foreach (PropertyValueCollection col in pc)
{
Console.WriteLine(col.PropertyName + " : " + col.Value);
Console.WriteLine();
}
}
}
}
}
}
端点
本技巧是我之前在 CodeProject 上为问题 Active Directory 登录[^] 提供的答案的一部分。
感谢您花费宝贵的时间阅读本技巧/窍门。 任何建议都将不胜感激。