检查是否启用了UserPrincipal
本文关键字:UserPrincipal 启用 是否 检查 | 更新日期: 2023-09-27 18:17:23
我正在使用c#代码来查询活动目录。我遇到的主要问题是确定一个帐户是否已被禁用。浏览许多在线文章,似乎不能完全依赖属性UserPrincipal。Enabled用于确定用户帐户是否已启用。很公平,因为它是一个可空的布尔值,但是当AD管理员禁用帐户时,它似乎被设置为false。我遇到的问题是,当我查询客户端的AD时,我发现大多数用户帐户UserPrincipal对象对此属性返回false。因此,当我使用以下代码检查一个帐户是否被禁用时:
private bool IsUserEnabled(UserPrincipal userPrincipal)
{
bool isEnabled = true;
if (userPrincipal.AccountExpirationDate != null)
{
// Check the expiration date is not passed.
if (userPrincipal.AccountExpirationDate <= DateTime.Now)
{
Log.DebugFormat("User {0} account has expired on {1}", userPrincipal.DisplayName, userPrincipal.AccountExpirationDate.Value);
isEnabled = false;
}
}
if (userPrincipal.IsAccountLockedOut())
{
isEnabled = false;
Log.DebugFormat("User {0} account is locked out", userPrincipal.DisplayName);
}
if (userPrincipal.Enabled != null)
{
isEnabled = userPrincipal.Enabled.Value;
Log.DebugFormat("User {0} account is Enabled is set to {1}", userPrincipal.DisplayName, userPrincipal.Enabled.Value);
}
return isEnabled;
}
由于userPrincipal.Enabled
检查,大多数帐户显示为禁用。
但是,如果我忽略这一点,只依赖于帐户到期日期和帐户锁定属性,那么我可能会错过使用Active Directory中的复选框禁用帐户而不设置帐户到期日期的人。
所有enabled返回false的帐户实际上是可以登录到域的活动帐户。
如何检查帐户是否实际启用?
我遇到了一个类似的问题,同样感到困惑!
我最初使用System.DirectoryServices.DirectorySearcher
来搜索禁用用户。AD用户记录的状态(禁用、锁定、密码过期等)存储在UserAccountControl属性中。您可以向DirectorySearcher传递一个过滤器,通过指定UserAccountControl属性作为过滤器的一部分来定位(比方说)禁用的帐户。
我从来都不喜欢这种方法,因为它相当于使用一个魔术字符串和一些魔术数字来构建查询;例如,这是用于定位禁用帐户的过滤器:
var searcher = new DirectorySearcher(dirEntry)
{
Filter = "(UserAccountControl:1.2.840.113556.1.4.803:=2)",
PageSize = 50
};
当我切换到使用UserPrincipal时,我很高兴看到这个很方便的"Enabled"属性在类上。至少在我意识到它没有返回与DirectorySearcher过滤器将返回的相同的值之前是这样。
不幸的是,我能找到的唯一可靠的方法来确定帐户是否实际启用是挖掘底层DirectoryEntry对象,并直接去检查UserAccountControl属性,即:
var result = (DirectoryEntry)userPrincipal.GetUnderlyingObject();
var uac = (int)result.Properties["useraccountcontrol"].Value;
var isEnabled = !Convert.ToBoolean(uac & 2);
注意- UserAccountControl属性是一个"flags" enum;UserAccountControl属性的所有可能值可以在这里找到:https://msdn.microsoft.com/en-us/library/aa772300(v=vs.85).aspx
我最终将上面的代码片段构建为一个小扩展方法;幸运的是,做这个额外的工作来检索UserAccountControl属性并没有明显减慢我的AD查询。
我通过展开结果得到了一个解决方案,然后到基数并展开基数。您将在那里看到enabled属性。然后右键单击表达式并添加到watch,并将watch表达式复制到我的代码中。
using (var context = new PrincipalContext(ContextType.Domain, "xyz.com", "Administrator", "xyz123"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DrectoryEntry;
foreach (String key in de.Properties.PropertyNames)
{
Console.WriteLine(key + " : " + de.Properties[key].Value);
}
Console.WriteLine("Enabled: " +((System.DirectoryServices.AccountManagement.AuthenticablePrincipal)(result)).Enabled);
Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
}
}
}
Console.ReadLine();
((System.DirectoryServices.AccountManagement.AuthenticablePrincipal)(result)).Enabled
在用户列表中为true或false
我可以告诉你在我的一个应用程序中什么对我有用。下面是我的应用程序的一个片段:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain.com"))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(pc, "Doe, John"))
{
Console.Out.Write(user.Enabled);
}
}
对于我来说,这可以准确地返回帐户是否启用。