C # Web Dav, почему запрос головы генерирует 401?

Ниже приведены 2 фрагмента кода, используемые для проверки существования папки в библиотеке документов SharePoint. Метод PROPFIND работает, в то время как другой метод с использованием HEAD приводит к ошибке 401.

Может кто-нибудь, пожалуйста, скажите мне, почему? Не отвлекайтесь на учетные данные, я установил их одинаковыми в обоих примерах, и все работает нормально....

Вот код, который работает:

// Create the web request object
var oReq = (HttpWebRequest)WebRequest.Create(url);

// Set the needed properties
oReq.Method = "PROPFIND";
oReq.Credentials = this.wsLists.Credentials; // Use same credentials as wsLists. 
oReq.AllowAutoRedirect = true;
oReq.UserAgent = "Microsoft-WebDAV-MiniRedir/6.1.7600";

// Enumerate through top level only, increasing the depth will find children.
oReq.Headers["Depth"] = "0";
oReq.Headers["translate"] = "f";
var oRequest = new StreamWriter(oReq.GetRequestStream());
oRequest.WriteLine();
oRequest.Close();
var oResponse = new StreamReader(oReq.GetResponse().GetResponseStream());
string sResponse = oResponse.ReadToEnd();
oResponse.Close();

и вот код нарушения:

private bool MossResourceExists(string url)
{
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "HEAD";

    // Create a new CredentialCache object and fill it with the network
    // credentials required to access the server.
    var myCredentialCache = new CredentialCache();
    if (!string.IsNullOrEmpty(this.Domain ))
    {
        myCredentialCache.Add(new Uri(url),
       "NTLM",
       new NetworkCredential(this.Username , this.Password , this.Domain )
       );
    }
    else
    {
        myCredentialCache.Add(new Uri(url),
       "NTLM",
       new NetworkCredential(this.Username , this.Password )
       );
    }

    request.Credentials = myCredentialCache;

    try
    {
        request.GetResponse();
        return true;
    }
    catch (WebException ex)
    {
        var errorResponse = ex.Response as HttpWebResponse;

        if (errorResponse != null)
            if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                return false;
            else
                throw new Exception("Error checking if URL exists:" + url + ";Status Code:" + errorResponse.StatusCode + ";Error Message:" + ex.Message ) ;
    }
    return true;
}

person JL.    schedule 05.01.2010    source источник


Ответы (3)


Мои два цента:

Я думаю, это связано с тем, как работает WebDAV:

  • первый запрос всегда отправляется анонимно, так как WebDAV является протоколом «запрос/ответ». Этот первый запрос без заголовков аутентификации необходим; ответ от WebDAV содержит одноразовый номер для проверки следующего запроса, помогая отразить, например, атаки воспроизведения. (из ответа на этот вопрос, см. ссылки в ответе для получения дополнительной информации).

  • Находится ли сайт, к которому вы пытаетесь получить доступ, в зону «Местная интрасеть» в IE? Если нет, следующее может дать дополнительную информацию о вашей проблеме и возможном обходном пути:

Понимание того, почему это происходит

Когда вы используете Internet Explorer для доступа к сайту WebDAV, Internet Explorer использует службы HTTP Windows (WinHTTP). WinHTTP отправляет учетные данные пользователя только в ответ на запросы, возникающие на сайте локальной интрасети во время процесса входа в систему с проверкой подлинности. Однако WinHTTP не проверяет параметры зоны безопасности в Internet Explorer, чтобы определить, является ли веб-сайт сайтом локальной интрасети. Вместо этого WinHTTP зависит от параметров прокси-сервера в Internet Explorer, чтобы определить, является ли веб-сайт сайтом локальной интрасети.

Если параметр Автоматически определять параметры не включен, любой определенный сценарий автоматической настройки не будет обрабатываться. WinHTTP не идентифицирует сайт WebDAV как сайт локальной интрасети. Поэтому WinHTTP отправит запрос без учетных данных пользователя, и вам будет предложено ввести учетные данные пользователя.

Как видите, эта проблема появляется только на сайте Экстранета, а не на сайте Интрасети. К сожалению, многие из моих клиентов используют геофизические решения по всей стране без промежуточных прокси. Из здесь.

person Colin    schedule 06.01.2010

Запрос не сгенерировал 401. 401 пришел с сервера. Вам следует просмотреть журналы событий Windows, журнал IIS и журналы SharePoint на сервере, чтобы понять, почему сервер вернул ошибку 401.

person John Saunders    schedule 05.01.2010
comment
Вы правы в отношении происхождения 401, но сервер сгенерировал 401 во время запроса во втором примере... - person JL.; 05.01.2010
comment
У меня нет под рукой SharePoint API. Говорится ли, что он поддерживает HEAD для этого запроса? - person John Saunders; 05.01.2010
comment
Я рассматривал его как стандартный веб-Dav. Другое дело, что для базовой библиотеки документов и папки на 1 уровень ниже это работает... только генерирует 401 для папок на 2 уровня ниже.... - person JL.; 05.01.2010

Я думаю, что ответ действительно действителен, и 401 здесь в порядке. Смотри, 401 означает "несанкционированный доступ". Таким образом, когда вы пытаетесь получить доступ к ресурсу, SharePoint сначала проверяет ваши учетные данные, чтобы узнать, разрешено ли вам это делать. Если у вас нет доступа, он вернет 401, если вы это сделаете, он вернет более 200 содержимого того, что вы запросили.

Теперь, в чем разница между ними:

  • когда вы запрашиваете ресурс, к которому у вас нет доступа
  • когда вы запрашиваете несуществующий ресурс

Основной принцип в SharePoint - если у вас нет доступа к какой-то вещи, то она для вас НЕ СУЩЕСТВУЕТ, и вы НЕ ДОЛЖНЫ знать, существует она или нет.

Если SharePoint разрешил вам HEAD для ресурса, к которому у вас нет доступа, вы можете попытаться найти http://sharepointsite/docs/JL_Gets_A_Salary_bonus.doc, чтобы узнать, есть ли у вас надбавка к зарплате или нет.

Вот почему вы получаете «доступ запрещен» как к ресурсам, к которым у вас нет доступа, так и к несуществующим ресурсам.

person naivists    schedule 06.01.2010