Sharepoint Web服务 – HTTP请求未经授权,客户端身份validationscheme为'Ntlm'。 从服务器收到的validation头是“NTLM”

我知道有类似这样的很多问题,但我找不到这个问题。

首先有几点:

  • 无法控制我们的Sharepoint服务器。 我无法调整任何IIS设置。
  • 我相信我们的IIS服务器版本是IIS 7.0。
  • 我们的Sharepoint服务器正在通过NTLM预测请求。
  • 我们的Sharepoint服务器与我的客户端计算机位于同一个域中。
  • 我正在使用.NET Framework 3.5,Visual Studio 2008

我正在尝试编写一个简单的控制台应用程序来使用Sharepoint Web服务来操作Sharepoint数据。 我已经添加了服务引用,下面是我的app.config:

<system.serviceModel> <bindings> <basicHttpBinding> <binding name="ListsSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="Transport"> <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="https://subdomain.companysite.com/subsite/_vti_bin/Lists.asmx" binding="basicHttpBinding" bindingConfiguration="ListsSoap" contract="ServiceReference1.ListsSoap" name="ListsSoap" /> </client> </system.serviceModel> 

这是我的代码:

 static void Main(string[] args) { using (var client = new ListsSoapClient()) { client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("username", "password", "domain"); client.GetListCollection(); } } 

当我调用GetListCollection()时,会引发以下MessageSecurityException

 The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM'. 

用一个内部的WebException:

 "The remote server returned an error: (401) Unauthorized." 

我已经尝试了各种绑定和各种代码调整,以尝试正确authentication,但无济于事。 我将在下面列出。


我已经尝试了以下步骤:

在创build客户端之前使用本机Win32 Impersonator

 using (new Impersonator.Impersonator("username", "password", "domain")) using (var client = new ListsSoapClient()) { client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("dpincas", "password", "domain"); client.GetListCollection(); } 

这产生了相同的错误信息。


为我的客户端凭据设置TokenImpersonationLevel

 using (var client = new ListsSoapClient()) { client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; client.GetListCollection(); } 

这产生了相同的错误信息。


使用安全模式= TransportCredentialOnly

 <security mode="TransportCredentialOnly"> <transport clientCredentialType="Ntlm" /> </security> 

这导致了一个不同的错误消息:

 The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via 

但是,我需要使用https,所以我不能改变我的URIscheme。


我尝试了一些我不记得的组合,但是当我这样做的时候我会把它们贴出来。 我真的在这里结束了。 我在Google上看到很多关于“切换到Kerberos”的链接,但是我的服务器似乎只接受NTLM,而不是“Negotiate”(就像它正在寻找Kerberos一样),所以很不幸。

任何帮助,乡亲?

Visual Studio 2005

  1. 在Visual Studio中创build一个新的控制台应用程序项目
  2. 将一个“Web引用”添加到Lists.asmx Web服务。
    • 您的url可能如下所示: http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
    • 我命名我的Web引用: ListsWebService
  3. 在program.cs中编写代码(这里有一个问题列表)

这是代码。

 using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace WebServicesConsoleApp { class Program { static void Main(string[] args) { try { ListsWebService.Lists listsWebSvc = new WebServicesConsoleApp.ListsWebService.Lists(); listsWebSvc.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; listsWebSvc.Url = "http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx"; XmlNode node = listsWebSvc.GetList("Issues"); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } } 

Visual Studio 2008

  1. 在Visual Studio中创build一个新的控制台应用程序项目
  2. 右键点击References和Add Service Reference
  3. 将URL添加到服务器上的Lists.asmx服务
    • 例如: http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
  4. 点击Go
  5. 点击OK
  6. 进行以下代码更改:

从以下位置更改app.config文件:

 <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> 

至:

 <security mode="TransportCredentialOnly"> <transport clientCredentialType="Ntlm"/> </security> 

更改您的program.cs文件并将以下代码添加到您的主要function:

 ListsSoapClient client = new ListsSoapClient(); client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials; client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; XmlElement listCollection = client.GetListCollection(); 

添加使用语句:

 using [your app name].ServiceReference1; using System.Xml; 

参考: http : //sharepointmagazine.net/technical/development/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list

经过大量的试验和错误之后,在我等待与我们的服务器人员交谈的机会之后停滞不前,我终于有机会与他们讨论这个问题,并问他们是否不介意转换我们的Sharepoint身份validation转到Kerberos。

令我惊讶的是,他们说这不会是一个问题,事实上很容易做到。 他们启用了Kerberos ,我修改了我的app.config,如下所示:

 <security mode="Transport"> <transport clientCredentialType="Windows" /> </security> 

作为参考,我的app.config中的完整serviceModel条目如下所示:

 <system.serviceModel> <bindings> <basicHttpBinding> <binding name="TestServerReference" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2000000" maxBufferPoolSize="2000000" maxReceivedMessageSize="2000000" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="Transport"> <transport clientCredentialType="Windows" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="https://path/to/site/_vti_bin/Lists.asmx" binding="basicHttpBinding" bindingConfiguration="TestServerReference" contract="TestServerReference.ListsSoap" name="TestServerReference" /> </client> </system.serviceModel> 

在此之后,一切都像魅力一样。 我现在可以(最终!)利用Sharepoint Web服务。 因此,如果其他人无法让他们的Sharepointnetworking服务使用NTLM,请参阅是否可以说服系统pipe理员切换到Kerberos。

在许多没有奏效的答案之后,当IIS服务器上的“匿名访问”被禁用时,我终于find了一个解决scheme。 我们的服务器使用Windows身份validation,而不是Kerberos。 这是由于这个博客张贴 。

没有对web.config进行更改。

在服务器端,ISAPI文件夹中的.SVC文件使用MultipleBaseAddressBasicHttpBindingServiceHostFactory

该服务的类属性是:

 [BasicHttpBindingServiceMetadataExchangeEndpointAttribute] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] public class InvoiceServices : IInvoiceServices { ... } 

在客户端,使其工作的关键是http绑定安全属性:

 EndpointAddress endpoint = new EndpointAddress(new Uri("http://SharePointserver/_vti_bin/InvoiceServices.svc")); BasicHttpBinding httpBinding = new BasicHttpBinding(); httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm; InvoiceServicesClient myClient = new InvoiceServicesClient(httpBinding, endpoint); myClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; (call service) 

我希望这对你有用!

如果我没有记错,将SharePoint Web服务添加为VS2K8“服务参考”存在一些问题。 您需要将其添加为旧式的“Web引用”才能正常工作。

我有相同的设置,你做的,这对我来说很好。 我认为,也许问题在于苔藓configuration或networking上的某处。

你说苔藓和你的应用程序位于同一个域中。 如果你有访问你的用户的网站(这是login到你的机器)…你有没有尝试过:

 client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials; 

上周我有同样的问题 – WCF程序在一台服务器上performance奇怪 – 为什么?

对我来说,解决办法很简单。 Sharepoint拥有自己的一组权限。 我的客户端尝试以未明确授予通过Sharepointpipe理面板访问Web服务的用户身份login。

我将用户添加到Sharepoint的白名单和砰 – 它只是工作。

即使这不是问题,请注意

HTTP请求未经客户authenticationscheme“Ntlm”的授权。 从服务器收到的validation头是“NTLM”。

意思(英文),你根本没有权限。 你的协议可能是正确的 – 你的用户只是没有权限。

我会试着用这个工具连接到你的Sharepoint网站。 如果这样做,你可以确定问题出在你的代码/configuration中。 这可能不会立即解决您的问题,但它排除了服务器有问题。 假设它不起作用,我会研究以下内容:

  • 你的用户是否真的有足够的权利在网站上?
  • 有干扰的代理吗? (你的configuration看起来有点像代理,你可以绕过吗?)

我认为使用安全模式Transport没有问题,但是我不太确定proxyCredentialType="Ntlm" ,也许这应该设置为None

我以前有过这个问题。

 client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; 

在拨打电话之前,对您的wcf代理执行此操作。

尝试这个

 <client> <endpoint> <identity> <servicePrincipalName value="" /> </identity> </endpoint> </client> 

在webfarm工作之前,我遇到过这个错误,并且为我修复了这个错误。

这个问题对我们来说更加奇怪。 如果您之前在浏览器中访问过SharePoint站点,则在您进行SOAP调用之前,一切正常。 但是,如果您先执行SOAP调用,则会抛出上述错误。

我们能够通过在客户端上安装Sharepoint证书并将域添加到本地Intranet站点来解决此问题。