【问题标题】:Verify if password is correct验证密码是否正确
【发布时间】:2011-04-25 11:51:15
【问题描述】:

我需要验证用户的密码是否正确。

我有这个代码:

 private bool checkOldPasswordValid(string password, string username)
    {
        using (DirectoryEntry entry = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
        {
            entry.Username = username;
            entry.Password = password;

            DirectorySearcher searcher = new DirectorySearcher(entry);

            searcher.Filter = "(objectclass=user)";
            try
            {
                searcher.FindOne();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
    }

但是WinNt不支持目录搜索器,所以我找到了另一种循环遍历所有记录的方法。

 foreach (DirectoryEntry dc in entry.Children)
            {
                // prints the name
                System.Diagnostics.Debug.WriteLine(dc.Name);
            }

但这只是获取名称而不验证密码。

请帮忙。谢谢

【问题讨论】:

    标签: c# asp.net active-directory passwords directoryentry


    【解决方案1】:

    要针对 LDAP 或 WinNT 进行身份验证,您不需要 DirectorySearcher。您只需要从您的DirectoryEntry 实例中获取NativeObject。这是一个代码示例,可能会指导您完成整个过程。

    public bool Authenticate(string username, string password, string domain) {
        bool authenticated = false;
    
        using (DirectoryEntry entry = new DirectoryEntry(@"WinNT://" + domain, username, password) {
            try {
                object nativeObject = entry.NativeObject;
                authenticated = true;
            } catch (DirectoryServicesCOMException ex) {
            }
        }
    
        return authenticated;
    }
    

    此代码将返回用户是否真实。一旦您可以使用此DirectoryEntry 类实例获取 NativeObject 属性,这意味着 AD(或本地计算机)使用模拟来获取此对象。如果您在没有抛出异常的情况下获取对象,则这意味着 AD(或本地计算机)能够对模拟用户进行身份验证。

    虽然您可以通过不指定用户名和密码而仅指定域(或本地计算机)来使用当前经过身份验证的用户,但通过指定用户名和密码,您表示要使用模拟,因此安全基础架构将使用给定用户名和密码,以尝试从此 DirectoryEntry 类实例中检索 NativeObject 属性。

    要针对 AD 进行身份验证,只需将 "WinNT://" 替换为 "LDAP://"

    【讨论】:

    • 如果域有时是空白的怎么办.. 这会是个问题吗?
    • 域可以是本地计算机名称,也可以是使用 AD 的域控制器中的域。通常,域不应为空。我从未测试过空白域,但我想这会导致try...catch 抛出。最好是进行单元测试,然后为每个参数尝试所有可能的值。
    • DirectoryEntry entry = new DirectoryEntry("WinNT://" + Environment.MachineName, Session["userName"].ToString(), password);
    • 我做了以上。即使密码错误,它也在验证
    • 在 ASP.NET 中,如果我没记错的话,您需要在配置文件中设置一些设置,以便告诉它使用模拟。 Mystere Man 提供的链接告诉您必须设置为truefalse。这在使用 ASP.NET 时有点不同。此代码在我开发的框架安全块中运行良好。也许对你来说正确的解决方案是两个答案的组合,神秘人和我的。
    【解决方案2】:

    您可以使用 DirectoryEntry 本身。

    在此处查看示例:http://support.microsoft.com/kb/316748

    你为什么还要使用 WinNT://?

    【讨论】:

    • 假设本地帐户不是 Active Directory 的一部分,.. 这就是为什么.. 但我不确定.. 如果您有更多信息,请告诉我.. 谢谢
    • 他使用 WinNT:// 对计算机本身而不是 AD 进行身份验证。
    • @user175084:使用 AD 时,您不应该管理本地帐户。让我解释。假设用户在本地计算机上进行身份验证,然后希望访问网络资源。即使您以本地计算机已知的身份对该用户进行了身份验证,但如果 AD 不知道该用户,AD 也不会让该用户获得他需要的任何资源。如果您希望管理本地计算机用户帐户,情况就不同了。
    • 那么,使用 LogonUser 会简单得多,不是吗?
    • @Mystere Man:我完全同意!但是我们不能判断一个人在做什么,因为我们不知道他正在从事的项目的各个方面,所以根据所提出的问题中暴露的内容提供解决方案更简单。此外,也许有人希望通过必须使用当前登录用户无法访问的某些特权的服务或应用程序来模拟服务帐户。尤其如此,因为 Microsoft 建议为需要处理特定敏感数据的“用户”创建服务帐户,但任何普通用户都不应访问。
    猜你喜欢
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    相关资源
    最近更新 更多