System.DirectoryServices - 服务器无法运行

时间:2011-10-28 15:23:58

标签: asp.net active-directory windows-authentication directoryservices

我的网站出现错误,我使用Windows身份验证。

奇怪的事情:

  • 仅当用户尚未保存到数据库(新未知用户)时才会出现
  • 仅在实时系统上出现,在本地开发环境中一切正常

这是我在日志邮件中收到的内容:

  

来源:System.DirectoryServices

     

消息:服务器无法运行。

     

跟踪:
  在System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  在System.DirectoryServices.DirectoryEntry.Bind()
  在System.DirectoryServices.DirectoryEntry.get_AdsObject()
  在System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
  在System.DirectoryServices.DirectorySearcher.FindOne()
  在Smarthouse.Labs.DataAccess.UserListManager.SaveUser(String windowsUserName)

这就是我实现DirectorySearch的方式:

private void SaveUser(string windowsUserName)
{
    string[] domainAndUser = windowsUserName.Split('\\');
    string domain = domainAndUser[0];
    string username = domainAndUser[1];

    DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain);
    DirectorySearcher search = new DirectorySearcher(entry);

    try
    {
        // Bind to the native AdsObject to force authentication.
        search.Filter = "(SAMAccountName=" + username + ")";
        search.PropertiesToLoad.Add("cn");
        search.PropertiesToLoad.Add("sn");
        search.PropertiesToLoad.Add("givenName");
        search.PropertiesToLoad.Add("mail");

        SearchResult result = search.FindOne();

        if (result == null)
        {
            throw new Exception("No results found in Windows authentication.");
        }

        User userToSave = new User();
        userToSave.FirstName = (String) result.Properties["givenName"][0];
        userToSave.LastName = (String) result.Properties["sn"][0];
        userToSave.Email = (String) result.Properties["mail"][0];
        userToSave.Username = windowsUserName;
        userToSave.Guid = Guid.NewGuid();

        SaveUser(userToSave);
    }
    catch (Exception ex)
    {
        throw new Exception("Error authenticating user. " + ex.Message, ex);
    }
    finally
    {
        //Dispose service and search to prevent leek in memory
        entry.Dispose();
        search.Dispose();
    }
}

如果需要更多代码示例,请告诉我。

4 个答案:

答案 0 :(得分:20)

您的问题是您正在使用“普通”域名进行绑定 - 这在LDAP中无效。实际上,如果您尝试绑定到LDAP://MyDomain,那么真正做的就是尝试绑定到名为MyDomain服务器

您需要一个有效的LDAP绑定字符串 - 类似LDAP://dc=yourdomain,dc=local或其他内容。

要了解您的默认LDAP绑定上下文是什么,请使用以下代码段:

DirectoryEntry deRoot = new DirectoryEntry("LDAP://RootDSE");

if (deRoot != null)
{
   string defaultNamingContext = deRoot.Properties["defaultNamingContext"].Value.ToString();
}

获得该字符串后 - 将其用作LDAP服务器的绑定字符串。

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

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

// set up domain context -- no domain name needed, uses default domain 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);

if(user != null)
{
   // do something here....     
}

新的S.DS.AM让您可以轻松地与AD中的用户和群组一起玩!

答案 1 :(得分:1)

要添加到marc_s's answer above,我需要搜索多个域。 因此,对于每个域,我执行了以下操作:

DirectoryEntry deRoot = new DirectoryEntry("LDAP://" +"DomainName"+ "/RootDSE");
string defaultNamingContext = "LDAP://" + deRoot.Properties["defaultNamingContext"].Value.ToString();
DirectoryEntry mySearchRoot = new DirectoryEntry(defaultNamingContext);
DirectorySearcher myDirectorySearcher = new DirectorySearcher(mySearchRoot);

答案 2 :(得分:0)

您可以使用LDAP://mydomain.com:389格式的绑定字符串。尝试使用LDAP:// DC = mydomain,DC = com时,我一直收到“Access is Denied”。一旦我切换到LDAP://mydomain.com:389格式,并在构建我的DirectoryEntry时使用AuthenticationTypes.ServerBind标志绑定,它运行良好。这是在Azure App Service中。

答案 3 :(得分:0)

类似的错误发生在我身上(虽然它一直发生,而不是像这里指出的特定情况)因为Active Directory连接字符串错误。我使用的是公司,而不是产品。 如果存在,请使用适用于组织中其他应用的内容。