C# 如何防止DirectoryOperationException-服务器无法处理目录请求
我正试图编写一个实用程序方法来更新C#中的AD属性(目前仅为单值字符串属性)。这是一个独立的实用程序,不依赖IIS。此方法将用于将人力资源系统中的数据加载到广告中 我能够使用System.DirectoryServices.Protocols有效地读取对象和属性。但是,当我调用ModifyRequest方法时,我得到一个DirectoryOperationException,消息是“服务器无法处理目录请求” 基于另一个堆栈溢出问题: 我尝试将端口636用于SSL LDAP,但它没有改变行为 我没有使用IIS,并且在.NET 4.5上,因此.NET/IIS的Microsoft修补程序不应应用 谷歌在这方面的搜索毫无结果 如果您知道发生此错误的原因以及如何修复,我将非常感激 代码如下。。请假设Conn包含来自封闭实用程序类的有效且经过身份验证的LDAP连接——如果需要,我可以提供封闭实用程序类的完整源代码 异常发生在C# 如何防止DirectoryOperationException-服务器无法处理目录请求,c#,directoryservices,C#,Directoryservices,我正试图编写一个实用程序方法来更新C#中的AD属性(目前仅为单值字符串属性)。这是一个独立的实用程序,不依赖IIS。此方法将用于将人力资源系统中的数据加载到广告中 我能够使用System.DirectoryServices.Protocols有效地读取对象和属性。但是,当我调用ModifyRequest方法时,我得到一个DirectoryOperationException,消息是“服务器无法处理目录请求” 基于另一个堆栈溢出问题: 我尝试将端口636用于SSL LDAP,但它没有改变行为 我
ModifyStringAttributeValue
中的SendRequest
行上:
using System;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.Net;
namespace MyOrganization.Common.Ldap
{
public class LdapSession
{
public bool UseKerberos { set; get; }
public String Host { set; get; }
public String UserId { set; get; }
public String Password { set; get; }
public String Tag { set; get; }
public int Port { set; get; }
public const int DefaultLdapPort = 389;
protected LdapConnection Conn;
public void EstablishV2()
{
}
public void Establish()
{
var effectivePort = Port == 0 ? DefaultLdapPort : Port;
Console.WriteLine("EffectivePort={0}", effectivePort);
var identifier = new LdapDirectoryIdentifier(Host, effectivePort);
if (UseKerberos)
{
Conn = new LdapConnection(identifier)
{
AuthType = AuthType.Kerberos,
Timeout = new TimeSpan(0, 10, 0, 0),
SessionOptions =
{
ProtocolVersion = 3,
VerifyServerCertificate =
new VerifyServerCertificateCallback((con, cer) => true),
SecureSocketLayer = true
}
};
}
else
{
Conn = new LdapConnection(identifier)
{
AuthType = AuthType.Basic,
Timeout = new TimeSpan(0, 10, 0, 0)
};
// Console.WriteLine("LPA: Binding with {0}, {1}", UserId, Password); // QUARTZ
Conn.Bind(new NetworkCredential(UserId, Password));
}
}
public IEnumerable<SearchResultEntry> Search(string cx, string filter, SearchScope searchScope, params string[] attrib)
{
var s = new SearchRequest(cx, filter, searchScope, attrib)
{
SizeLimit = 0,
TimeLimit = new TimeSpan(1, 0, 0) // One hour, zero minutes, zero seconds
};
var raw = Conn.SendRequest(s);
if (raw == null)
{
throw new Exception("null response");
}
var r = raw as SearchResponse;
if (r != null)
{
// Console.WriteLine(Tag + "Search response entries: {0}", r.Entries.Count); // QUARTZ
foreach (SearchResultEntry e in r.Entries)
{
yield return e;
}
}
else
{
// Console.WriteLine(Tag + "Search response was null" ); // QUARTZ
}
yield break;
}
public ResultCode ModifyStringAttributeValues(string dn, IDictionary<string, string> modifications)
{
// declare the request and response objects here
// they are used in two blocks
ModifyRequest modRequest;
ModifyResponse modResponse;
try
{
// initialize the modRequest object
modRequest =
new ModifyRequest(dn);
modRequest.Controls.Add(new PermissiveModifyControl());
var mods = new DirectoryAttributeModification[modifications.Count];
int z = 0;
foreach (var pair in modifications)
{
var mod = new DirectoryAttributeModification();
mod.Operation = DirectoryAttributeOperation.Replace;
mod.Name = pair.Key;
mod.Add(pair.Value);
mods[z] = mod;
z += 1;
}
// cast the returned directory response into a ModifyResponse type
// named modResponse
modResponse =
(ModifyResponse)Conn.SendRequest(modRequest);
return modResponse.ResultCode;
}
catch (Exception e)
{
Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
e.GetType().Name, e.Message);
return ResultCode.Unavailable;
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.DirectoryServices.Protocols;
Net系统;
命名空间MyOrganization.Common.Ldap
{
公开课
{
公共bool UseKerberos{set;get;}
公共字符串主机{set;get;}
公共字符串用户标识{set;get;}
公共字符串密码{set;get;}
公共字符串标记{set;get;}
公共int端口{set;get;}
public const int DefaultLdapPort=389;
受保护的LDA连接接头;
公共图书馆v2()
{
}
公共图书馆
{
var effectivePort=Port==0?DefaultLdapPort:Port;
WriteLine(“EffectivePort={0}”,EffectivePort);
var标识符=新的LdapDirectoryIdentifier(主机、有效端口);
如果(使用Kerberos)
{
Conn=新的LdapConnection(标识符)
{
AuthType=AuthType.Kerberos,
超时=新的时间跨度(0,10,0,0),
会话选项=
{
协议版本=3,
验证服务器证书=
新的VerifyServerCertificateCallback((con,cer)=>true),
SecureSocketLayer=true
}
};
}
其他的
{
Conn=新的LdapConnection(标识符)
{
AuthType=AuthType.Basic,
超时=新的时间跨度(0,10,0,0)
};
//WriteLine(“LPA:Binding with{0},{1}”,UserId,Password);//QUARTZ
Conn.Bind(新的网络凭证(用户ID、密码));
}
}
公共IEnumerable搜索(字符串cx、字符串筛选器、SearchScope SearchScope、参数字符串[]属性)
{
var s=新的搜索请求(cx、筛选器、searchScope、attrib)
{
SizeLimit=0,
TimeLimit=newtimespan(1,0,0)//一小时零分零秒
};
var raw=连接发送请求;
如果(原始==null)
{
抛出新异常(“空响应”);
}
var r=原始响应;
如果(r!=null)
{
//Console.WriteLine(标记+“搜索响应条目:{0}”,r.entries.Count);//QUARTZ
foreach(r.Entries中的SearchResultEntry e)
{
收益率e;
}
}
其他的
{
//Console.WriteLine(标记+“搜索响应为空”);//石英
}
屈服断裂;
}
public ResultCode ModifyStringAttributeValue(字符串dn、IDictionary修改)
{
//在此处声明请求和响应对象
//它们分两个区块使用
ModifyRequest-modRequest;
ModifyResponse-modResponse;
尝试
{
//初始化modRequest对象
modRequest=
新修改请求(dn);
添加(新的PermissionModifyControl());
var mods=newdirectoryattributemodification[modifications.Count];
int z=0;
foreach(修改中的var对)
{
var mod=new DirectoryAttributeModification();
mod.Operation=DirectoryAttributeOperation.Replace;
mod.Name=pair.Key;
模加(对值);
mods[z]=mod;
z+=1;
}
//将返回的目录响应强制转换为ModifyResponse类型
//命名modResponse
模态响应=
(ModifyResponse)Conn.SendRequest(modRequest);
返回modResponse.ResultCode;
}
捕获(例外e)
{
Console.WriteLine(“\n发生意外异常:\n\t{0}:{1}”,
e、 GetType().Name,e.Message);
返回ResultCode.Unavailable;
}
}
}
}
我知道代码有点笨重,而且充满了奇怪的注释——它是在我运行时从Microsoft网站上的示例代码中剪切、粘贴和修改的。这可能是服务器证书检查的问题(例如,如果您的服务器是自动签名的) 下面是一些绕过服务器证书检查建立SSL连接的测试代码:
public static LdapConnection GetLdapConnection(string login, string password)
{
var serverName = /*myServerNameFromConfig*/;
var port = /*myPortFromConfig*/;
LdapDirectoryIdentifier ldi = new LdapDirectoryIdentifier(string.Format("{0}:{1}", serverName, port));
NetworkCredential nc = new NetworkCredential(login, password);
LdapConnection connection = new LdapConnection(ldi, nc, System.DirectoryServices.Protocols.AuthType.Basic);
connection.SessionOptions.ProtocolVersion = 3;
connection.SessionOptions.VerifyServerCertificate =
new VerifyServerCertificateCallback((con, cer) => true);
connection.SessionOptions.SecureSocketLayer = true;
return connection;
}