Использование пользовательской службы REST, размещенной внутри Sharepoint 2010, с проверкой подлинности Windows

Существует эта специальная служба WCF REST, размещенная внутри приложения Sharepoint 2010 с использованием проверки подлинности Windows.

Мне нужно использовать эту службу в проекте .NET (т.е. в консольном проекте), но учетные данные сводят меня с ума. Я получаю много ответов 400 - bad request или 401 - unauthorized (в зависимости от того, включаю ли я проверку подлинности или нет).

Позвольте мне привести Вам пример:

siteUri — это URL-адрес сайта SP (корневая/домашняя страница), а methodUri — это URL-адрес метода службы, который возвращает XML.

Опять же, этот сайт аутентифицирован Windows. Если я открою браузер и перейду к methodUri, я получу:

Ошибка запроса

Сервер обнаружил ошибку при обработке запроса. Смотрите журналы сервера для более подробной информации.

Но если затем я перейду к siteUri, загрузится домашняя страница Sharepoint, а затем я снова смогу перейти к methodUri, и теперь я правильно получаю ответ XML.

Таким образом, кажется, что при просмотре домашней страницы сохраняются некоторые файлы cookie, которые затем используются при выполнении запроса к веб-методу. Проверяя запросы в Fiddler, я могу подтвердить это:

Первый запрос methodUri завершается с ошибкой с кодом 400 и не содержит файлов cookie в заголовке запроса. Затем, когда я просматриваю домашнюю страницу (siteUri), появляется несколько запросов/ответов, которые, похоже, являются самой аутентификацией. Заголовок ответа включает:

WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAABDh+CIwTbjqQAAAAA=
Set-Cookie: WSS_KeepSessionAuthenticated={b89d78b2-063d-4ac4-810e-bde4e04a829e}; path=/
Persistent-Auth: true

И наконец, при повторном просмотре methodUri первым ответом будет 401 - Несанкционировано, но сразу после этого есть еще один запрос, включающий эти заголовки.

Cookie: WSS_KeepSessionAuthenticated={b89d78b2-063d-4ac4-810e-bde4e04a829e}
Authorization: Negotiate oXcwdaADCgEBoloEWE5UTE1TU1AAAwAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAABXCiOIGAbEdAAAAD37/i76Dl3jNyK8bIRz57fmjEgQQAQAAAPUXp1AtIpqEAAAAAA==

которые, наконец, принимаются, и служба отвечает соответствующим XML.

Таким образом, браузер достаточно умен, чтобы обрабатывать эти запросы/ответы туда и обратно для аутентификации текущего пользователя Windows.

Моя проблема в том, как я могу сделать это в .NET (3.5 или 4), но БЕЗ использования учетных данных по умолчанию, мне нужно указать имя пользователя, pwd и домен.

Я потратил 5 дней на это, и я мог заставить его работать, используя сетевые учетные данные по умолчанию в HttpWebRequest, но когда я устанавливаю учетные данные вручную (используя те же, что и для текущего вошедшего в систему пользователя), это не работает.

Я просто нахожу все это излишне сложным (спасибо, Microsoft), потому что я работаю с открытым исходным кодом (ruby, python), и такие вещи просто просты.

Надеюсь, я ясно выразился, если вам нужна дополнительная информация, просто спросите. Я готов отдать всю свою репутацию в награду за это.

Спасибо


person empz    schedule 10.01.2013    source источник
comment
Можете ли вы опубликовать код о том, как вы настраиваете свой клиент?   -  person Luis    schedule 11.01.2013


Ответы (1)


Ну, я исправил это.

Это код, который я использовал. Спасибо Microsoft за такие простые и понятные объяснения.

var siteUri = @"http://sharepoint-site-uri";
var methodUri = @"http://sharepoint-site-uri/namespace/service/method";
string responseXml = null;

var request = (HttpWebRequest)WebRequest.Create(siteUri);
var cc = new CredentialCache { { new Uri(siteUri), "NTLM", new NetworkCredential("user", "pwd", "domain") } };
request.Credentials = cc;

try
{
    // first site request
    var response = (HttpWebResponse)request.GetResponse();
    if (response.StatusCode == HttpStatusCode.OK)
    {
        request = (HttpWebRequest)WebRequest.Create(uri);
        request.CookieContainer = new CookieContainer();

        // copy the authentication cookies from the response
        foreach (Cookie c in response.Cookies)
        {
            request.CookieContainer.Add(c);
        }

        request.ContentType = "application/xml; charset=utf-8";

        // second request, now against the service url
        using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
        {
            // get the response text
            responseXml = reader.ReadToEnd();
        }
    }
}
catch (Exception e)
{       
   // handle error
}
person empz    schedule 11.01.2013