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
- 在Visual Studio中创build一个新的控制台应用程序项目
- 将一个“Web引用”添加到Lists.asmx Web服务。
- 您的url可能如下所示:
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
- 我命名我的Web引用:
ListsWebService
- 您的url可能如下所示:
- 在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
- 在Visual Studio中创build一个新的控制台应用程序项目
- 右键点击References和Add Service Reference
- 将URL添加到服务器上的Lists.asmx服务
- 例如:
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
- 例如:
- 点击Go
- 点击OK
- 进行以下代码更改:
从以下位置更改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站点来解决此问题。