C# 从HttpHandler调用SharePoint搜索web服务错误(NTLM)
以下是我的场景:我有一个正在使用的SharePoint站点,它位于一个服务器场上。在这个站点中,我创建了一个HttpHandler,它使用位于不同服务器上的SharePoint搜索Web服务。看起来像这样:C# 从HttpHandler调用SharePoint搜索web服务错误(NTLM),c#,web-services,sharepoint,httphandler,ntlm,C#,Web Services,Sharepoint,Httphandler,Ntlm,以下是我的场景:我有一个正在使用的SharePoint站点,它位于一个服务器场上。在这个站点中,我创建了一个HttpHandler,它使用位于不同服务器上的SharePoint搜索Web服务。看起来像这样: BasicHttpBinding binding = new BasicHttpBinding(); binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; binding.Security.Transp
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
QueryServiceSoapClient _queryService = new QueryServiceSoapClient(binding, new EndpointAddress("http://easearch.ea.com/_vti_bin/search.asmx"));
_queryService.ClientCredentials.Windows.AllowNtlm = true;
_queryService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
_queryService.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
//_queryService.ClientCredentials.Windows.ClientCredential = new NetworkCredential("MyUsername", "MyPassword", "MyDomain"); //This is the only way it seems to work
//NetworkCredential userCredential = CredentialCache.DefaultCredentials.GetCredential(_queryService.Endpoint.ListenUri, "NTLM");
//_queryService.ClientCredentials.Windows.ClientCredential = userCredential;
string status = _queryService.Status();
- 在服务器B上具有对SharePoint search web服务的服务引用
- 具有使用服务引用调用搜索服务的http处理程序
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
QueryServiceSoapClient _queryService = new QueryServiceSoapClient(binding, new EndpointAddress("http://easearch.ea.com/_vti_bin/search.asmx"));
_queryService.ClientCredentials.Windows.AllowNtlm = true;
_queryService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
_queryService.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
//_queryService.ClientCredentials.Windows.ClientCredential = new NetworkCredential("MyUsername", "MyPassword", "MyDomain"); //This is the only way it seems to work
//NetworkCredential userCredential = CredentialCache.DefaultCredentials.GetCredential(_queryService.Endpoint.ListenUri, "NTLM");
//_queryService.ClientCredentials.Windows.ClientCredential = userCredential;
string status = _queryService.Status();
如果我在我的dev box上的控制台应用程序中使用此代码,它将按预期工作。但是当我尝试使用http处理程序中的相同代码时,它会给出错误
HTTP请求未经授权
客户端身份验证方案“Ntlm”。
接收到的身份验证标头
来自服务器的是“NTLM”
我已经尝试了上述代码的多种不同组合,只有当我直接提供凭据时,我的HttpHandler才有效。有人有什么想法吗
谢谢。NTLM无法将凭据委派给远程服务器 这就是所谓的“双跳”问题 您必须配置Kerberos。基本上:
- 将SharePoint配置为使用Kerberos(在管理中心的“身份验证提供程序”中)
- 在应用程序池帐户上为SharePoint创建SPN(使用命令行“setspn”)
- 在运行此网站的应用程序帐户上,在服务器B上为网站runnong创建SPN
- 配置2个服务器之间的委派
是的,Kerberos没有那么容易实施…谢谢。我还使用了另一篇文章,上面有同样的信息,还有一些使用搜索web服务的选项。不幸的是,在我的组织中,Kerberos似乎没有得到很好的支持,因此我可能无法使用它。我还被告知,在另一篇文章中建议的DisableLoopbackCheck也不能解决我的问题。看来我必须找到另一种方法来做我需要的事。不过再次谢谢你。