Используйте Invoke-WebRequest с именем пользователя и паролем для базовой проверки подлинности в API GitHub

Начальный вопрос

С помощью cURL мы можем передать имя пользователя с веб-запросом HTTP следующим образом:

$ curl -u <your_username> https://api.github.com/user

Флаг -u принимает имя пользователя для аутентификации, а затем cURL запрашивает пароль. Пример cURL для Базовая аутентификация с помощью GitHub Api.

Как мы также передаем имя пользователя и пароль вместе с Invoke-WebRequest? Конечной целью является пользователь PowerShell с базовой аутентификацией в API GitHub.

Изменить (это то, что работает)

Заметки из Wikipedia на Basic Auth с клиентской стороны.

Объедините имя пользователя и пароль в одну строку username:password

$user = "shaunluttin"
$pass = "super-strong-alpha-numeric-symbolic-long-password"
$pair = "${user}:${pass}"

Кодировать строку в RFC2045-MIME-вариант Base64, за исключением, не ограничиваясь этим, 76 char/line.

$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)

Создайте значение Auth как метод, пробел, а затем закодированную пару Method Base64String

$basicAuthValue = "Basic $base64"

Создайте заголовок Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

$headers = @{ Authorization = $basicAuthValue }

Вызовите веб-запрос

Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers

Спасибо @briantist за помощь!

Обсуждение

Версия PowerShell более сложная, чем версия cURL. Почему это? @briantist отметил, что GitHub нарушает RFC, и PowerShell придерживается этого. Означает ли это, что cURL также нарушает стандарт?

Ответ 1

Я предполагаю базовую аутентификацию здесь.

$cred = Get-Credential
Invoke-WebRequest -Uri 'https://whatever' -Credential $cred

Вы можете получить свои учетные данные другими способами (Import-Clixml и т.д.), Но это должен быть объект [PSCredential].

Редактировать на основе комментариев:

GitHub нарушает RFC, как они объясняют по предоставленной вами ссылке:

API поддерживает базовую аутентификацию, как определено в RFC2617, с небольшими отличиями. Основное различие заключается в том, что RFC требует, чтобы на запросы, не прошедшие проверку подлинности, было получено 401 ответ. Во многих местах это раскрыло бы существование пользовательских данных. Вместо этого GitHub API отвечает 404 Not Found. Это может вызвать проблемы для библиотек HTTP, которые принимают 401 несанкционированный ответ. Решение состоит в том, чтобы вручную создать заголовок авторизации.

Насколько мне известно, Powershell Invoke-WebRequest ожидает ответа 401 перед отправкой учетных данных, а поскольку GitHub никогда не предоставляет их, ваши учетные данные никогда не будут отправлены.

Построить заголовки вручную

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

Обычная аутентификация принимает строку, состоящую из имени пользователя и пароля, разделенных пользователем двоеточия user:pass а затем отправляет результат, закодированный в Base64.

Код, подобный этому, должен работать:

$user = 'user'
$pass = 'pass'

$pair = "$($user):$($pass)"

$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))

$basicAuthValue = "Basic $encodedCreds"

$Headers = @{
    Authorization = $basicAuthValue
}

Invoke-WebRequest -Uri 'https://whatever' -Headers $Headers

Вы могли бы объединить некоторые из конкатенации строк, но я хотел разбить их, чтобы сделать их более понятными.

Ответ 2

Используйте это:

$root = 'REST_SERVICE_URL'
$user = "user"
$pass= "password"
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)

$result = Invoke-RestMethod $root -Credential $credential

Ответ 3

Invoke-WebRequest следует RFC2617, как отметил @briantist, однако есть некоторые системы (например, JFrog Artifactory), которые разрешают анонимное использование, если заголовок Authorization отсутствует, но будут отвечать 401 Forbidden если заголовок содержит недействительные учетные данные.

Это можно использовать для запуска ответа 401 Forbidden и получения -Credentials для работы.

$login = Get-Credential -Message "Enter Credentials for Artifactory"

                              #Basic foo:bar
$headers = @{ Authorization = "Basic Zm9vOmJhcg==" }  

Invoke-WebRequest -Credential $login -Headers $headers -Uri "..."

Это отправит неверный заголовок в первый раз, который будет заменен действительными учетными данными во втором запросе, поскольку -Credentials переопределяет заголовок Authorization.

Протестировано с Powershell 5.1

Ответ 4

Я должен был сделать это, чтобы заставить это работать:

$pair = "$($user):$($pass)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Pair))
$headers = @{ Authorization = "Basic $encodedCredentials" }
Invoke-WebRequest -Uri $url -Method Get -Headers $headers -OutFile Config.html

Ответ 5

Другой способ - использовать certutil.exe. Сохраните имя пользователя и пароль в файле, например, в .txt как имя пользователя: пароль.

certutil -encode in.txt out.txt

Теперь вы должны иметь возможность использовать значение auth из out.txt

$headers = @{ Authorization = "Basic $((get-content out.txt)[1])" }
Invoke-WebRequest -Uri 'https://whatever' -Headers $Headers