Active directory 从dmz进行LDAP访问失败::无法检索有关域的信息(1355)

Active directory 从dmz进行LDAP访问失败::无法检索有关域的信息(1355),active-directory,ldap,Active Directory,Ldap,尝试从dmz中的iis服务器访问ldap服务器,并获取错误消息:无法检索有关域的信息(1355)。有关于附加dns信息或使用基础对象的文章,但是这些解决方案对我不起作用,所以请不要在谷歌搜索和发布同样的错误建议 我重写了整个图层以使用主体对象。这至少给了我一个很好的错误信息 using System; using System.Collections; using System.Collections.Generic; using System.DirectoryServices; using

尝试从dmz中的iis服务器访问ldap服务器,并获取错误消息:无法检索有关域的信息(1355)。有关于附加dns信息或使用基础对象的文章,但是这些解决方案对我不起作用,所以请不要在谷歌搜索和发布同样的错误建议

我重写了整个图层以使用主体对象。这至少给了我一个很好的错误信息

using System;
using System.Collections;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Web;
using TheDomain.Common.Extensions;

namespace MobileApplications
{
    public class Ldap35: IDisposable
    {
        private string _ldapserver;
        private string _adminUser;
        private string _adminPassword;
        private PrincipalContext _connection;
        private UserPrincipal _userData;
        private IList<string> _groups;

    public delegate void MessagingHandler(string message);
    public event MessagingHandler Messaged;

    public Ldap35(string server, string adminuser, string adminpassword)
    {
        _ldapserver = server;
        _adminPassword = adminpassword;
        _adminUser = adminuser;
    }
    /// <summary>
    /// this will basically instantiate a UserPrincipal
    /// </summary>
    /// <param name="username">just the user</param>
    /// <param name="pass">just the password</param>
    /// <param name="domain">the correct domain, not sure if this is thedoamin.com or the_domain</param>
    /// <returns></returns>
    public bool Authenticate(string username, string pass, string domain)
    {
        if ( _connection == null)
            EstablishDirectoryConnection();

            ValidateConnection();
            if (!domain.IsEmpty() && !username.Contains("\\") && !username.Contains("/"))
                username = domain + "\\" + username;

            _userData = UserPrincipal.FindByIdentity(_connection, username);

            if (_userData == null)
                throw new ApplicationException("Unable to locate user.");

            if (! _connection.ValidateCredentials(username, pass))
                throw new ApplicationException("Invalid credentials.  Unable to log in.");

            //_userData = new UserPrincipal( _connection, username, pass, true );

            return true;
    }

    public bool Authenticate(string username, string pass)
    {
        return Authenticate(username, pass, "");
    }

    public bool IsMemeberOfGroup(string group)
    {
       ValidateConnection(); ValidateUser();
        return _userData.IsMemberOf(new GroupPrincipal(_connection));
    }

    public bool IsMemeberOfGroup(string group, bool caseSensitive)
    {
        if (caseSensitive)
            return IsMemeberOfGroup(group);

        GetGroups();

        return _groups.Any(g => g.ToLower().Trim() == group.ToLower().Trim());

    }

//        public IList<string> GetGroups()
//        {
//            if ( _groups == null )
//                _groups = new List<string>();
//
//            ValidateConnection(); ValidateUser();
//          
//                var results = _userData.GetGroups();
//
//                foreach (var principal in results)
//                {
//                    _groups.Add(principal.Name);
//                }
//         
//            return _groups;
//        }

    public IList<string> GetGroups()
    {
        if (_groups == null)
            _groups = new List<string>();

        ValidateConnection(); ValidateUser();
        Print("Getting groups");
        DirectoryEntry de = (DirectoryEntry)_userData.GetUnderlyingObject();
        object obGroups = de.Invoke("Groups");
        foreach (object ob in (IEnumerable)obGroups)
        {
            // Create object for each group.

            var obGpEntry = new DirectoryEntry(ob);
            Print(obGpEntry.Name);
            _groups.Add(obGpEntry.Name);
        }
        return _groups;
    }

    /// <summary>
    /// PrincipalContext class to establish a connection to the target directory and specify credentials for performing operations against the directory. This approach is similar to how you would go about establishing context with the DirectoryContext class in the ActiveDirectory namespace.
    /// </summary>
    /// <param name="adminuser">a user with permissions on the domain controller</param>
    /// <param name="adminpassword">the password to go with the above</param>
    /// <returns></returns>
    private void EstablishDirectoryConnection()
    {
        _connection = new PrincipalContext(ContextType.Domain, _ldapserver, "DC=thedomain,DC=com", ContextOptions.SimpleBind, _adminUser, _adminPassword);
    }

    private void Print(string message)
    {
        if (Messaged != null)
            Messaged(message);
    }

    private void ValidateConnection()
    {
        if ( _connection == null)
             throw new ApplicationException("No connection to server, please check credentials and configuration.");
    }

    private void ValidateUser()
    {
        if (_userData == null)
            throw new ApplicationException("User is not authenticated.  Please verify username and password.");
    }

    public void Dispose()
    {
        _userData.Dispose();
        _connection.Dispose();
    }
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.DirectoryServices;
使用System.DirectoryServices.AccountManagement;
使用System.Linq;
使用System.Web;
使用domain.Common.Extensions;
命名空间MobileApplications
{
公共类Ldap35:IDisposable
{
私有字符串_ldapserver;
私有字符串\u adminUser;
私有字符串\u adminPassword;
private PrincipalContext\u连接;
私有用户主体_userData;
私营IList_集团;
公共委托无效消息处理程序(字符串消息);
已发送公共事件MessagingHandler消息;
公共Ldap35(字符串服务器、字符串管理员用户、字符串管理员密码)
{
_ldapserver=server;
_adminPassword=adminPassword;
_adminUser=adminUser;
}
/// 
///这将基本上实例化一个UserPrincipal
/// 
///只有用户
///只有密码
///正确的域,不确定这是doamin.com还是\u域
/// 
公共bool身份验证(字符串用户名、字符串传递、字符串域)
{
if(_connection==null)
建立目录连接();
ValidateConnection();
如果(!domain.IsEmpty()&&!username.Contains(\\)&&!username.Contains(“/”)
用户名=域+“\\”+用户名;
_userData=UserPrincipal.FindByIdentity(_连接,用户名);
如果(_userData==null)
抛出新的ApplicationException(“无法定位用户”);
if(!\u connection.ValidateCredentials(用户名,密码))
抛出新的ApplicationException(“无效凭据。无法登录”);
//_userData=newuserprincipal(_连接,用户名,密码,true);
返回true;
}
公共bool身份验证(字符串用户名、字符串密码)
{
返回Authenticate(用户名,pass,“”);
}
公共bool IsMeberOfGroup(字符串组)
{
ValidateConnection();ValidateUser();
返回_userData.IsMemberOf(新的组主体(_连接));
}
public bool IsMeBeerOfGroup(字符串组,bool区分大小写)
{
如果(区分大小写)
返回IsMeberOfGroup(组);
GetGroups();
返回_groups.Any(g=>g.ToLower().Trim()==group.ToLower().Trim());
}
//公共IList GetGroups()
//        {
//如果(_groups==null)
//_groups=新列表();
//
//ValidateConnection();ValidateUser();
//          
//var results=_userData.GetGroups();
//
//foreach(结果中的var本金)
//                {
//_groups.Add(主体名称);
//                }
//         
//返回组;
//        }
公共IList GetGroups()
{
如果(_groups==null)
_组=新列表();
ValidateConnection();ValidateUser();
打印(“获取组”);
DirectoryEntry de=(DirectoryEntry)_userData.getunderyingObject();
对象对象对象组=de.Invoke(“组”);
foreach(对象组中的对象对象对象)
{
//为每个组创建对象。
var obGpEntry=新目录条目(ob);
打印(obGpEntry.Name);
_添加(obGpEntry.Name);
}
返回组;
}
/// 
///PrincipalContext类建立到目标目录的连接,并指定对该目录执行操作的凭据。此方法类似于在ActiveDirectory命名空间中使用DirectoryContext类建立上下文。
/// 
///在域控制器上具有权限的用户
///与上述内容一起使用的密码
/// 
私有目录连接()
{
_连接=新的PrincipalContext(ContextType.Domain,\u ldapserver,“DC=thedomain,DC=com”,ContextOptions.SimpleBind,\u adminUser,\u adminPassword);
}
私有无效打印(字符串消息)
{
如果(已发送消息!=null)
消息(message);
}
私有void ValidateConnection()
{
if(_connection==null)
抛出新的ApplicationException(“未连接到服务器,请检查凭据和配置”);
}
私有void ValidateUser()
{
如果(_userData==null)
抛出新的ApplicationException(“用户未经过身份验证。请验证用户名和密码。”);
}
公共空间处置()
{
_Dispose();
_connection.Dispose();
}
}
}
这篇文章为我指明了正确的方向。虽然这真的没有意义。我采用了一种比我在上面发布的更为现代的方法,使用了以下主要对象:

var _connection = new PrincipalContext(ContextType.Domain, 
                                       _ldapserver, 
                                       "DC=domain,DC=com", 
                                       ContextOptions.SimpleBind, 
                                       _adminUser, 
                                       _adminPassword);
var _userData = UserPrincipal.FindByIdentity(_connection, username);
这允许我将正确的权限传递给域控制器,但是UserPrinicpal对象上的get groups方法抛出了1155错误

我使用旧方法解决了这个问题,如下所示。现在一切正常

DirectoryEntry de = (DirectoryEntry)_userData.GetUnderlyingObject();
object obGroups = de.Invoke("Groups");

顺便说一句,如果有人能告诉我如何正确格式化我的代码片段,使它们显示得很好,那将是一个额外的收获。由于某些原因,我每次都失败了。服务器甚至可以从DMZ找到并联系LDAP源吗?通常,从DMZ到内部网络的访问受到严格限制。所以你们可能需要从我开始提问