Веб-службы Sharepoint. HTTP-запрос неавторизован с помощью схемы аутентификации клиента "Ntlm". Заголовок аутентификации, полученный с сервера, был "NTLM",
Я знаю, что много вопросов о SO аналогично этому, но я не мог найти его для этой конкретной проблемы.
Несколько точек, во-первых:
- У нас есть без контроля на нашем сервере Sharepoint. Я не могу настроить любые настройки IIS.
- Я считаю, что наша версия сервера IIS - IIS 7.0.
- Наш сервер Sharepoint ожидает запросы через NTLM.
- Наш сервер Sharepoint находится в том же домене, что и мой клиентский компьютер.
- Я использую .NET Framework 3.5, Visual Studio 2008
Я пытаюсь написать простое консольное приложение для управления данными Sharepoint с помощью веб-служб 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."
Я пробовал различные привязки и различные настройки кода, чтобы попытаться аутентифицироваться должным образом, но безрезультатно. Я приведу список ниже.
Я пробовал следующие шаги:
Использование собственного 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, поэтому я не могу изменить схему URI.
Я пробовал некоторые другие комбинации, которые я не помню, но я опубликую их, когда буду. Я действительно нахожусь здесь. Я вижу много ссылок на Google, которые говорят "переключитесь на Kerberos", но мой сервер, похоже, принимает NTLM, а не "Negotiate" (как было бы сказано, если он ищет Kerberos), так что, к сожалению, это не вариант.
Любая помощь там, люди?
Ответы
Ответ 1
После большого количества проб и ошибок, за которым последовал застойный период, пока я ждал возможности поговорить с нашими парнями-серверами, я наконец-то имел возможность обсудить проблему с ними и спросил их, не будут ли они против переключения наша аутентификация Sharepoint для Kerberos.
К моему удивлению, они сказали, что это не проблема, и на самом деле это было легко сделать. Они активировали Kerberos, и я изменил свой app.config следующим образом:
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
Для справки, моя полная запись serviceModel в моем app.config выглядит так:
<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 Services. Итак, если кто-то еще не сможет заставить свои веб-службы Sharepoint работать с NTLM, посмотрите, можете ли вы убедить системных администраторов переключиться на Kerberos.
Ответ 2
Visual Studio 2005
- Создайте новый проект консольного приложения в Visual Studio
- Добавить веб-ссылку в веб-службу Lists.asmx.
- Ваш URL-адрес, вероятно, будет выглядеть следующим образом:
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
- Я назвал свою веб-ссылку:
ListsWebService
- Напишите код в 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
- Щелкните правой кнопкой мыши ссылку и добавьте ссылку службы
- Поместите URL-адрес в службу List.asmx на свой сервер
- Пример:
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
- Нажмите Go
- Нажмите "ОК"
- Выполните следующие изменения кода:
Измените файл app.config на:
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
To:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
Измените файл program.cs и добавьте следующий код в свою основную функцию:
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:
using [your app name].ServiceReference1;
using System.Xml;
Ссылка: http://sharepointmagazine.net/technical/development/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list
Ответ 3
После многих ответов, которые не сработали, я наконец нашел решение, когда анонимный доступ отключен на сервере IIS. Наш сервер использует проверку подлинности Windows, а не Kerberos. Это благодаря этой публикации в блоге.
В web.config изменений не было.
На стороне сервера файл .SVC в папке ISAPI использует 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)
Надеюсь, это сработает для вас!
Ответ 4
Если я правильно помню, есть некоторые проблемы с добавлением веб-служб SharePoint в качестве ссылки на службы поддержки VS2K8. Вам нужно добавить его как "Web Reference" в старом стиле для правильной работы.
Ответ 5
У меня такая же настройка, что и у вас, и это отлично работает для меня. Я думаю, что, возможно, проблема лежит где-то в вашей конфигурации мха или в вашей сети.
Вы сказали, что moss находится в том же домене, что и ваше приложение. Если у вас есть доступ к сайту с вашим пользователем (который зарегистрирован на вашем компьютере)... вы пробовали:
client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
Ответ 6
У меня была точно такая же проблема на прошлой неделе - Программа WCF ведет себя странно на одном сервере - почему?
Для меня решение было довольно простым. У Sharepoint есть собственный набор разрешений. Мой клиент попытался войти в систему как пользователь, которому явно не был предоставлен доступ к веб-сервису через панель управления SharePoint.
Я добавил пользователя в белый список Sharepoint и bang - он просто сработал.
Даже если это не проблема, обратите внимание, что
HTTP-запрос неавторизован с помощью схемы аутентификации клиента "Ntlm. Заголовок аутентификации, полученный с сервера, был" NTLM.
Значит (на английском языке), что у вас просто нет разрешения. Вероятно, ваш протокол прав - ваш пользователь просто не имеет прав.
Ответ 7
Я попытался бы подключиться к вашему сайту Sharepoint с помощью этого инструмента здесь. Если это работает, вы можете быть уверены, что проблема в вашем коде/конфигурации. Возможно, это не решит вашу проблему сразу, но это исключает, что с сервером что-то не так. Если предположить, что он не работает, я бы исследовал следующее:
- У вашего пользователя действительно есть достаточные права на сайте?
- Есть ли прокси-сервер, который вмешивается? (Ваша конфигурация немного похожа на прокси. Можете ли вы ее обходить?)
Я думаю, что нет ничего плохого в использовании режима безопасности Transport, но я не уверен в proxyCredentialType="Ntlm"
, возможно, это должно быть установлено None.
Ответ 8
У меня была эта проблема раньше.
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
сделайте это против своего прокси-сервера wcf перед выполнением вызова.
Ответ 9
Попробуйте это
<client>
<endpoint>
<identity>
<servicePrincipalName value="" />
</identity>
</endpoint>
</client>
Я столкнулся с этой ошибкой раньше, когда работал в webfarm, и это исправило это для меня.
Ответ 10
Эта проблема была еще более странной для нас. Все работает, если вы ранее посещали сайт sharepoint из браузера, прежде чем вы сделали SOAP-вызов. Однако, если вы сначала выполнили вызов SOAP, мы бы выбросили вышеуказанную ошибку.
Мы смогли решить эту проблему, установив сертификат sharepoint на клиенте и добавив домен на локальные сайты интрасети.