【问题标题】:Cannot access sn, givenName in LDAP无法访问 LDAP 中的 sn、givenName
【发布时间】:2013-06-01 03:24:18
【问题描述】:

我是 C# 的新手,我使用 LDAP 来 1) 验证用户的登录凭据和 2) 为我的应用获取有关用户的其他信息。我们的 LDAP 服务器不允许我请求的某些数据匿名提供,所以我必须等到我与用户的完整凭据绑定才能提取数据。但是,即便如此,我也无法获得像 sn 和 givenName 这样的简单字段。使用 JXplorer,我可以看到这些值在匿名连接期间隐藏的位置,但使用完整的用户/SSL/密码组合,我可以看到 JXplorer 中的所有内容。我似乎无法通过我的代码做同样的事情。

如果我在第一个 FindOne() 之后遍历属性,则找到 9 个属性(没有一个是我要查找的属性)。如果我在 second FindOne() 之后遍历属性,则只有 4 个属性可用。这两个结果似乎都不受 PropertiesToAdd.Add("...") 的影响。

任何建议将不胜感激。

public string[] Authenticate(string user,  string password)
    {
         string[] results = new string [2];

        //Concatenate serverpath + username + container
        //I.e.  "LDAP://ldap.disney.com:636/CN=donaldDuck,ou=people,dc=la,dc=disney,dc=com"
        DirectoryEntry de = new DirectoryEntry(_ldapserver + "cn=" + user + "," + _topContainer);
        //User's password for initial verification
        de.Password = password;

        //initate anonymous bind
        de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;
        DirectorySearcher searcher = new DirectorySearcher(de);
        searcher.SearchScope = System.DirectoryServices.SearchScope.Base;

        //Search for first record
        SearchResult result = searcher.FindOne();

        //Check results
        if (result == null) throw new Exception(ERR_NOT_FOUND);

        de = result.GetDirectoryEntry();

        //Return search results
        //results[0] = (string)de.Properties["mail"].Value;
        // results[1] = (string)de.Properties["givenName"].Value + " " + (string)de.Properties["sn"].Value;
        // Distingushed Name of the found account
        string DN = de.Path.Substring(de.Path.ToUpper().IndexOf("CN="));
        // Close search connection
        de.Close();


        // now bind and verify the user's password,
        de = new DirectoryEntry(_ldapserver + _topContainer);
        de.Username = DN;
        de.Password = password;
        de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;

        //Obtain additional information
         searcher = new DirectorySearcher(de);
         searcher.PropertiesToLoad.Add("sn");
         searcher.PropertiesToLoad.Add("givenName");

         SearchResult r = searcher.FindOne();
         de = r.GetDirectoryEntry();

        foreach (string property in de.Properties.PropertyNames)
         {
           Console.WriteLine("\t{0} : {1} ", property, de.Properties[property][0]);
         }

        //End obtain additional information

        //Validate password
        Object obj = de.NativeObject;
        de.Close();

        //if we made it here, we successfully authenticated
        return results;
    }

【问题讨论】:

    标签: c# ldap


    【解决方案1】:

    如果您使用的是 .NET 3.5 及更高版本,则应查看 System.DirectoryServices.AccountManagement (S.DS.AM) 命名空间。在此处阅读所有相关信息:

    基本上,您可以定义域上下文并在 AD 中轻松找到用户和/或组:

    // set up domain context
    using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
    {
       // validate given user credentials
       bool isValid = ctx.ValidateCredentials(user, password);
    
       // find a user
       UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
    
       if(user != null)
       {
          string surname = user.Surname;
          string givenName = user.GivenName;
       }
    }    
    

    新的 S.DS.AM 让在 AD 中与用户和组一起玩变得非常容易!

    【讨论】:

    • 我确实认为这是一个选项,但我认为这仅适用于 MS AD。这是否适用于 Unix 或 Novell LDAP 服务器?
    • @user2023444:抱歉 - 不 - 这实际上仅适用于 Active Directory(我以为你正在使用它) - 如果不是:请说明你正在使用什么以及你正在反对什么!
    • Marc,抱歉,我不知道 LDAP 服务器品牌是什么,我只知道它不是 AD。但是,我确实设法解决了这个问题。看来,如果 DirectoryEntry(path) 构造函数需要完整的 DN 作为我绑定搜索中路径的一部分,而不仅仅是基础。有一次,我做到了,效果很好。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    相关资源
    最近更新 更多