带有 ADAM 用户和简单绑定的 ADAM 身份验证

Posted

技术标签:

【中文标题】带有 ADAM 用户和简单绑定的 ADAM 身份验证【英文标题】:ADAM authentication w/ ADAM user and simple bind 【发布时间】:2008-11-19 22:27:44 【问题描述】:

我已遵循 Microsoft 的 ADAM 分步指南,并在我的本地计算机上设置了一个 ADAM 实例。我正在尝试使用“Mary Baker”帐户进行身份验证,但每次我在下面的if (entry.Guid != null) 行中收到 COM 异常。异常表明存在未知用户名或错误密码。

但是,我可以使用 ldp 实用程序连接到 ADAM 并成功执行简单绑定 - 所以我知道用户名都存在,并且我有正确的密码。

此外,我已将用户的 msDS-UserAccountDisabled 属性设置为 false,并将用户添加到管理员和读者角色。

有什么想法吗?

    path = "LDAP://localhost:50000/O=Microsoft,c=US";
    userId = "CN=Mary Baker,OU=ADAM users,";
    password = "Mary@101";

    DirectoryEntry entry = new DirectoryEntry(path, userId, password, AuthenticationTypes.None);
    if (entry.Guid != null)
        LoadWelcomeScreen();

谢谢。

【问题讨论】:

【参考方案1】:

ADAM 将用户的唯一标识符存储在user 类的displayName 属性中。它们需要在 ADAM 实例中是唯一的,以便用户进行身份验证。如果两个用户都将其displayName 属性设置为“jsmith”,那么这两个用户都无法在 ADAM 中进行身份验证。

使用 ldp 实用程序在 displayName 中查询 Mary Baker。它可能是“mbaker”之类的东西。将该值用作给定代码中的 userId。

【讨论】:

【参考方案2】:

感谢 Ryan 关于 displayName 的提示。将我的测试课程发布在我当地的 ADAM 实例上,供任何可能感兴趣的人参考。

    [TestMethod]
    public void CreateUserAccount()
    
        var username = "amurray";
        var password = "ADAMComplexPassword1234";
        var firstname = "Andy";
        var lastname = "Murray";

        const AuthenticationTypes authTypes = AuthenticationTypes.Signing |
                                              AuthenticationTypes.Sealing |
                                              AuthenticationTypes.Secure;

        var ldapPath = "LDAP://localhost:389/OU=MyProject,OU=Applications,DC=Company,DC=ADAM";
        using (var dirEntry = new DirectoryEntry(ldapPath, "MyPC\\adamuser", "Password1!", authTypes))
        
            DirectoryEntry user = null;
            const int ADS_PORT = 389;
            const long ADS_OPTION_PASSWORD_PORTNUMBER = 6;
            const long ADS_OPTION_PASSWORD_METHOD = 7;
            const int ADS_PASSWORD_ENCODE_CLEAR = 1;

            try
            
                user = dirEntry.Children.Add(string.Format("CN=0 1", firstname, lastname), "user");
                user.Properties["displayName"].Value = username;
                user.Properties["userPrincipalName"].Value = username;
                user.Properties["msDS-UserAccountDisabled"].Value = false;
                user.Properties["msDS-UserDontExpirePassword"].Value = true;
                user.CommitChanges();
                var userid = user.Guid.ToString();

                // Set port number, method, and password.
                user.Invoke("SetOption", new object[]ADS_OPTION_PASSWORD_PORTNUMBER,ADS_PORT);
                user.Invoke("SetOption", new object[]ADS_OPTION_PASSWORD_METHOD,ADS_PASSWORD_ENCODE_CLEAR);

                user.Invoke("SetPassword", new object[] password);
                user.CommitChanges();
                user.Close();
            
            catch (Exception e)
            
                var msg = e.GetBaseException().Message;
                Console.WriteLine(e);
                System.Diagnostics.Debug.Print(msg);
                            
        
    


    [TestMethod]
    public void TestUserAuthentication()
    
        try
        
            var ldsContext = new PrincipalContext(ContextType.ApplicationDirectory, "localhost:389",
                                                  "OU=MyProject,OU=Applications,DC=Company,DC=ADAM",
                                                  ContextOptions.SimpleBind);

            // Returns true if login details are valid
            var isValid = ldsContext.ValidateCredentials("amurray", "ADAMComplexPassword1234", ContextOptions.SimpleBind);
        
        catch (Exception e)
        
            var msg = e.GetBaseException().Message;
            Console.WriteLine(e);
            System.Diagnostics.Debug.Print(msg);
        
    

【讨论】:

【参考方案3】:

我没有使用过 ADAM 或 System.DirectoryServices,但我确实有使用 LDAP 和 AD 的经验;希望以下内容适用。

我以前从未见过以这种格式给出的用户 ID。 (它看起来像是某种相对 DN,如尾随逗号所示?)您是否尝试将用户 ID 指定为完整 DN(根据标准 LDAP 的要求)或作为裸用户名(如果 ADAM 支持)?

在诊断这样的网络协议问题时(查看我的程序是否正在执行我认为我告诉它的操作,并查看它正在执行的操作与正常运行的程序正在执行的操作相比如何),我发现它很有帮助运行Wireshark 为非功能和功能操作,看看他们有什么不同。如果您从未使用过 Wireshark,希望上手不会太难:

    下载、安装并启动软件。 在捕获下,单击选项。 将接口设置为本地主机/环回或以太网接口。 (我不认为环回在 Windows 上按预期工作;您可能需要选择以太网接口并在 C# 代码中更新 LDAP URL 以使用您的主机名而不是 localhost。) 在捕获过滤器下,输入“tcp 端口 50000”(无引号)。 点击开始,运行连接操作,然后进入捕获菜单并点击停止。

Wireshark 可以为你分析协议,所以你不必自己熟悉协议细节,虽然你知道的越多,就越容易解释所有细节.您可以启动几个 Wireshark 实例来轻松比较两个不同的捕获(您的代码和 LDP)。

【讨论】:

以上是关于带有 ADAM 用户和简单绑定的 ADAM 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

无法针对 ADAM 对 SharePoint Extranet 站点进行身份验证

SharePoint 中的 ADAM 管理

使用 ADAM 进行身份验证。如何将 ApacheDS Studio 与 ADAM 连接

使用 LDAP 对 ADAM 进行身份验证

针对 ADAM 和 AD FS 的 ASP.NET MVC 3 SSO

使用 ADAM 验证 DMZ 区域中的用户