WCF的basicHttpBinding与Windows身份验证

4

我已经为这个问题烦恼了两个小时:(

各位朋友,

我正在尝试从控制台应用程序访问SharePoint OOTB列表Web服务。我的IIS中的SharePoint站点设置为集成Windows身份验证模式,并禁用匿名访问。

现在,在客户端我所做的是:

try            
{
   BasicHttpBinding bind = new BasicHttpBinding();
   bind.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
   bind.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
   EndpointAddress endpoint = new EndpointAddress("http://abc:37379/_vti_bin/lists.asmx");
   ServiceReference1.ListsSoapClient listService
       = new ConsoleApplication1.ServiceReference1.ListsSoapClient(bind, endpoint);
   var elm = listService.GetListItems("Tasks", null, null, null, "10", null, @"06dc3b48-a55e-4db8-8511-acbaf9748e15");
}
catch (Exception ex){
  Console.WriteLine("Message:\n" + ex.Message + "\nDetail:\n" +
  ex.ToString() + "\nStackTrace:\n" + ex.StackTrace);   }

出现异常:"HTTP请求未经客户端身份验证方案“Negotiate”进行身份验证。从服务器接收到的身份验证标头是'NTLM'。"

我真的很想像我们在旧的net 2.0时代所做的那样做些什么。

serviceProxy.Credentials = new NetworkCredentials("username","password","domain");

什么是在新代理类中实现这种凭证处理的最简单方法?(顺便说一句,正如您已经注意到的,我正在使用 Binding/endpoint 将所有内容放在代码中而不是配置文件中,这是我的应用程序的限制。请不要告诉我更改它-这是不可能的)。有人能帮我吗?非常感谢。

FYI:由于ASMX <> WCF,因此代理类当然是不同的。 - John Saunders
1个回答

4

据我所知,当Web服务器在绑定中指定了Kerberos(Windows),但尝试回退到NTLM时,就会出现这种情况。

您应该可以更改此代码行

bind.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

to

bind.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;

如果您需要使用Kerberos,则需要确保Web服务器上的服务运行在与服务主体名称在Active Directory中相同的帐户下。
如果您想指定凭据,请使用通道工厂创建客户端,并在打开通道之前,在通道工厂的凭据属性上设置适当的凭据。 例如:
var cf = new ChannelFactory<IServiceInterface>(
    bind, endpoint);
cf.Credentials.UserName.UserName = "domain\\someuser";
cf.Credentials.UserName.Password = "password";

看起来生成的代理也有一个凭据属性,允许您做同样的事情。 - jageall
非常感谢您的建议。 可惜它没有起作用。:( 您可以查看我在上面给chris.w.mclean的评论,了解我的问题描述以及我遇到的异常情况。 - Moim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接