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 Несанкционированный обратно. Все работает нормально, если я отключаю базовую аутентификацию на сайте. Так что я знаю, что это не проблема с сервером. Я могу POST, используя мой браузер.
Изменить: Таким образом, кажется, базовая аутентификация работает правильно, когда я отлаживаю на сервере. Но мой сервер возвращает перенаправление, которое затем заставляет Invoke-Webrequest интерпретировать это как 401.
Любая идея о том, почему это не может работать?
2 ответа
Вы получаете это поведение из-за перенаправления; при выполнении этого дополнительного запроса к месту перенаправления заголовок авторизации не включается.
По этой причине PowerShell 6.0.0 добавил параметр PreserveAuthorizationOnRedirect.
Указывает, что командлет должен сохранять заголовок авторизации, если он присутствует, при перенаправлениях.
По умолчанию командлет удаляет заголовок авторизации перед перенаправлением. Указание этого параметра отключает эту логику для случаев, когда заголовок необходимо отправить в место перенаправления.
В качестве альтернативы, если вы не используете 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();
Скорее всего, это связано с перенаправлением, как сказал pfx, вы также можете сделать MaximumRedirection 0 и поймать ошибку. Таким образом вы можете получить перенаправленный URL-адрес и попробовать еще раз.