c# - 检查是否启用了 UserPrincipal

标签 c# active-directory

我正在使用 C# 代码查询 Active Directory。我遇到的主要问题是确定帐户是否已被禁用。翻阅许多在线文章,似乎不能仅依靠属性 UserPrincipal.Enabled 来确定用户帐户是否已启用。很公平,因为它是一个可为 null 的 bool 值,但是当 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 时,我很高兴在类上看到这个方便的“已启用”属性。至少直到我意识到它没有返回与 DirectorySearcher 过滤器返回的值相同的值。

不幸的是,我能找到的确定帐户是否实际启用的唯一可靠方法是深入研究底层的 DirectoryEntry 对象,然后直接检查 UserAccountControl 属性,即:

var result = (DirectoryEntry)userPrincipal.GetUnderlyingObject();
var uac = (int)result.Properties["useraccountcontrol"].Value;
var isEnabled = !Convert.ToBoolean(uac & 2);

注意 - UserAccountControl 属性是一个“标志”枚举; UserAccountControl 属性的所有可能值都可以在这里找到:https://msdn.microsoft.com/en-us/library/aa772300(v=vs.85).aspx

我最终将上面的代码片段构建成一个小的扩展方法;幸运的是,为检索 UserAccountControl 属性做这些额外工作并没有显着减慢我的 AD 查询速度。

关于c# - 检查是否启用了 UserPrincipal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25245940/

相关文章:

c# - 从基础 asp.net 身份用户创建继承用户

c# - 在 C# 中向根 xelement 元素添加/创建命名空间

c# - 将 OpenID Connect 与事件目录联合服务 (ADFS) 结合使用时,如何包含对 id_token 的附加声明?

c# - 从 SID 获取 user@domain 而不是 domain\user

powershell - 对 Active Directory 数据进行排序

c# - IIS 部署在 cassini 中运行正常后,PrincipalContext.ValidateCredentials 停止验证

c# - Switch 语句性能 C#

c# - 当接口(interface)在单独的项目中时处理枚举

c# - 使用 Prism 创建基础加载 View

azure - 使用 PSKeyVaultCertificate 向 Azure 服务主体添加身份验证时出现请求错误