我需要以编程方式调用WCF服务。该服务可以使用 NTLM或Kerberos身份验证托管,并且需要在其中任何一个下工作。也就是说,如果通过Kerberos连接到服务失败,那么它应该回退到NTLM。
以下是我用于Kerberos身份验证的代码(如果相关,该服务托管在SharePoint 2010中,并且是从Web部件调用的):
public static SiteMembershipSvc.SiteMembershipServiceClient InitialiseSiteMembershipService(string url)
{
var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
url = url.EndsWith("/") ? url + SiteMembershipAddress : url + "/" + SiteMembershipAddress;
var endpoint = new EndpointAddress(url);
var proxy = new SiteMembershipSvc.SiteMembershipServiceClient(binding, endpoint);
proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
return proxy;
}
在NTLM环境中运行时在代理上调用方法会产生错误:
HTTP请求未经授权 客户认证方案 '谈判'。身份验证标头 从服务器收到的是'NTLM'。
注意:URL可能位于另一台服务器上的另一个Web应用程序中。我无法检查Web部件的Web应用程序运行的身份验证,并假设它与托管WCF服务的位置相同。
如何(自动或手动)确保身份验证在失败时从Kerberos回退到NTLM?
更新
如上所述,调用Web方法时会发生身份验证错误。但是我不想等待很长时间,因为在几个地方调用了多个Web方法。我想在配置代理的位置测试身份验证(在上面的代码片段中)。
我尝试过使用proxy.Open()
,但这似乎不会导致失败。
答案 0 :(得分:1)
这有点像曲线球,但为什么它会回归到NTLM。我在活动目录和WCF中的安全性都遇到了很大的困难,所有这些都与服务主体名称(SPN)有关。
如果您将服务作为网络服务之外的其他内容运行,则Kerberos将失败,除非您在域中为您的服务声明了SPN。要设置SPN,您需要Windows服务器管理工具包,其中包含命令setspn。
setspn -A HTTP\machinename domain\service_account
这将允许Kerberos在域内与您的服务共享客户端凭据。
请做一些阅读,因为根据您的设置,您可以在同一个盒子上运行任何其他服务的kerberos。
答案 1 :(得分:1)
(我认为原帖很老。)
你可以使用BasicHttpBinding以外的东西(比如WsHttpBinding)吗?根据{{3}}文章,BasicHttpBinding是绑定对象的一个例外,因为它不会自动协商。这就是allowNTLM无效的原因。
答案 2 :(得分:0)
我发布了与here相同的错误消息,并通过创建动态端点解决了这个问题:
public static SiteMembershipSvc.SiteMembershipServiceClient InitialiseSiteMembershipService(string url)
{
//create endpoint
EndpointAddress ep = new EndpointAddress(new Uri(string), EndpointIdentity.CreateUpnIdentity("MyDomain\WCFRunAsUser"));
//create proxy with new endpoint
SiteMembershipSvc.SiteMembershipServiceClient service = new SiteMembershipSvc.SiteMembershipServiceClient("wsHttp", ep);
//allow client to impersonate user
service.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
//return our shiny new service
return service;
}
我将WCF服务作为特定的Active Directory用户运行,而不是默认的NETWORK_SERVICE。
答案 3 :(得分:0)
答案 4 :(得分:0)
我猜您使用服务器的完整DNS名称作为服务的地址。尝试使用NETBIOS名称或IP地址。这应该迫使它使用NTLM。
如果您知道服务器使用的协议,您可以将应用配置为使用全名或IP。
希望对你有用。
答案 5 :(得分:0)
如果您的Kerberos失败,它将自动默认为NTLM,您不必做任何特殊的事情。
http://www.windowsecurity.com/articles/Troubleshooting-Kerberos-SharePoint-environment-Part1.html
http://www.windowsecurity.com/articles/Troubleshooting-Kerberos-SharePoint-environment-Part2.html
http://www.windowsecurity.com/articles/Troubleshooting-Kerberos-SharePoint-environment-Part3.html
答案 6 :(得分:0)
我无法找到自动执行此操作的方法。相反,我已经在必须选择身份验证类型的应用程序中添加了UI。