【问题标题】:Method returning 'true' when it should be returning 'false'当它应该返回“false”时返回“true”的方法
【发布时间】:2013-11-12 09:21:47
【问题描述】:

我正在使用 Active Directory DirectoryServices.AccountManagement API,并尝试使用以下代码连接到服务器:

PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, (server + ":" + port), loginUsername, loginPassword);

我想做的第一件事是检查loginUsernameloginPassword 是否有效并且在Active Directory 实例中具有足够的权限。为此,我调用以下命令:

bool x = principalContext.ValidateCredentials(null, null);

根据documentation,这将验证构造函数中指定的凭据,因为null 已传递。在调试器中,抛出如下错误,说明凭证为假:

然而,ValidateCredentials 检查的实际结果却奇怪地返回了true,因此代码继续执行。

如何解决?

编辑:

这是另一个详细说明错误的屏幕截图。如屏幕截图所示,我正在调用ValidateCredentials 方法,并为用户名和密码传递null 值,根据文档,这将尝试验证在 PrincipalContext 类的构造函数中传递的凭据。

屏幕截图还显示了通过的用户名和密码都是“测试”的,它们是无效的并且不存在于 Active Directory 中。该方法返回 true,即使显示了许多错误。

【问题讨论】:

  • 不确定:你的函数有异常和返回值?
  • 明确一点:您传递的凭据无效,您确实希望它返回true - 对吗?
  • 另外,您绝对确定构造函数中的凭据不为空吗?这听起来很像“如果在构造函数中没有指定凭据,并且用户名和密码参数为空,则此方法验证当前主体的默认凭据。”
  • 一个抛出异常的方法怎么能同时返回一个值(又不是out参数)? 编辑:您显示的异常是否在ValidateCredentials 方法中实际处理(被try-catch 捕获)?跨度>
  • 正确@MarcGravell。我故意在 PrincipalContext 构造函数中传递无效凭据以对其进行测试。并且 ValidateCredentials 方法返回 true,即使引发了内部错误,表明登录凭据为 false

标签: c# .net windows security active-directory


【解决方案1】:

您只需要停止查找空值...

if (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(username)) return false;

我进行了一些测试

    using (var pc = new PrincipalContext(ContextType.Domain, "mydomain.lan")){

    var isOk1 = pc.ValidateCredentials(null,null); //Always true
    var isOk2 = pc.ValidateCredentials("notexists","wrong"); //false
    var isOk2 = pc.ValidateCredentials("existing","correct"); //true
    }

    using (var pc = new PrincipalContext(ContextType.Domain, "mydomain.lan", "notright","wrong")){
        var isOk1 = pc.ValidateCredentials(null,null); //Always true
        var isOk2 = pc.ValidateCredentials("notexists","wrong"); //false
        var isOk2 = pc.ValidateCredentials("existing","correct"); //true
}

因此 ValidateCredentials 在上下文中并不真正需要用户...如果您在随后的查找中提供一个错误的用户组,但是会失败

是的,文档内容如下:

ValidateCredentials 方法绑定到构造函数中指定的服务器。如果用户名和密码参数为空,则验证构造函数中指定的凭据。如果构造函数中没有指定凭据,并且用户名和密码参数为空,则此方法验证当前主体的默认凭据。
(http://msdn.microsoft.com/en-us/library/bb154889%28v=vs.100%29.aspx)

但我无法验证,构造函数中的凭据是否在起作用

编辑:你已经接受了,但也许你可以用这个方法来解决你的问题?

 using (var pc = new PrincipalContext(ContextType.Domain, "domain.lan", username, password))
            {
                if (pc.ValidateCredentials(username, password))
                {
                    try
                    {
                        using (var searcher = new PrincipalSearcher(new UserPrincipal(pc)))
                        {
                            searcher.QueryFilter.SamAccountName = username;
                            Principal u = searcher.FindOne();
                        }
                    }
                    catch (Exception)
                    {
                        return "no rights to work on ad";
                    }
                }
                else
                {
                    return "user cannot login";
                }
            }

【讨论】:

  • 所以我应该在 ValidateCredentials 方法中传递它们而不是在构造函数中传递用户名和密码吗?如果是这样,如果帐户权限不足,但详细信息正确,它会返回 false 吗?从本质上讲,我试图限制低权限帐户访问 AD。
  • 这只是检查用户名/密码组合。你想检查对什么的权利?正在搜索/使用 AD?
  • @DotNET 查看我刚刚在对该问题的评论中链接的线程。是不是在域中配置了Guest帐户?或类似的东西。
  • 我的要求是应用程序必须首先对用户进行身份验证,并确保他有足够的权限访问 Active Directory,因为它可以在具有高安全性的封闭网络上运行。事实上这就是为什么我首先尝试通过构造函数传递凭据,因为如果用户帐户无法访问 Active Directory,那么我认为它在那个阶段将无法连接。
  • @Steen - 感谢您的建议。你能详细说明一下吗?据我了解,代码是试图对登录的用户进行查询,如果他没有足够的权限,它应该抛出异常吗?
猜你喜欢
  • 2012-07-07
  • 2014-01-11
  • 2013-09-20
  • 2019-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多