Invoke-Webrequest получает 401 при POST, но не при GET с базовой аутентификацией

У меня есть сайт разработки с включенной базовой аутентификацией. Я могу получить страницу, используя следующее, чтобы добавить базовую аутентификацию в заголовки:

$creds = "$($BASIC_AUTH_USER):$($BASIC_AUTH_PASS)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($creds))
$basicAuthValue = "Basic $encodedCreds"
$headers = @{
    Authorization = $basicAuthValue
}

$login = Invoke-WebRequest $url -SessionVariable session -UseBasicParsing -Headers $headers

Но я не могу опубликовать тот же URL:

$fields = @{ Email = $SITE_USER; Password = $SITE_PASS; }
$login = Invoke-WebRequest -Uri $url -Method POST -WebSession $session -Body $fields -UseBasicParsing -Headers $headers

Я получаю ответ 401 Unauthorized. Все работает нормально, если я отключу базовую авторизацию на сайте. Так что я знаю, что это не проблема сервера. Я могу POST с помощью моего браузера.

Изменить: кажется, что базовая аутентификация работает правильно, когда я отлаживаю сервер. Но мой сервер возвращает перенаправление, из-за чего Invoke-Webrequest интерпретирует это как ошибку 401.

Любая идея о том, почему это может не работать?


person sheamus    schedule 03.10.2018    source источник
comment
Разве 401 не является несанкционированным, что означает, что у вас нет разрешения на POST?   -  person Maximilian Burszley    schedule 04.10.2018
comment
Я могу размещать сообщения на этом сайте из браузера. Если я отключу базовую авторизацию на сайте, то скрипт сработает. Так что да, я считаю, что у меня есть разрешение на публикацию.   -  person sheamus    schedule 05.10.2018


Ответы (1)


Вы получаете такое поведение из-за перенаправления; при выполнении этого дополнительного запроса к местоположению перенаправления заголовок авторизации не включается.

По этой причине в PowerShell 6.0.0 добавлен параметр PreserveAuthorizationOnRedirect.

Указывает, что командлет должен сохранять заголовок Authorization, если он присутствует, при перенаправлении.
По умолчанию командлет удаляет заголовок Authorization перед перенаправлением. Указание этого параметра отключает эту логику для случаев, когда заголовок необходимо отправить в место перенаправления.

справочник по Invoke-WebRequest


В качестве альтернативы, если вы не используете PowerShell 6, вы можете обойти это с помощью скрипта более низкого уровня, используя System.Net.WebRequest, который определяет свойство AllowAutoRedirect, для которого можно установить значение False в чтобы пропустить перенаправление после успешного POST, избегая ошибки 401.

Обратите внимание, что вы должны сами позаботиться о таких вещах, как форматирование данных/тела (json, form-urlencoded,...) и http-заголовки.

Скрипт будет выглядеть так, как показано ниже.
Обратите внимание на строку с AllowAutoRedirect = $false.

$creds = "$($BASIC_AUTH_USER):$($BASIC_AUTH_PASS)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($creds))
$basicAuthValue = "Basic $encodedCreds"

$url = "http://your.url"
$request = [System.Net.WebRequest]::CreateHttp($url);   
$request.Method = "post"
$request.Headers.Add("Authorization", $basicAuthValue)
$request.AllowAutoRedirect = $false

$body = "your formatted data goes here"
$bytes = [System.Text.Encoding]::UTF8.GetBytes($body);
$stream = $request.GetRequestStream()
$stream.Write($bytes, 0, $bytes.Length);
$stream.Close();

$request.GetResponse();
person pfx    schedule 05.10.2018