Використовуйте Invoke-WebRequest з ім'ям користувача та паролем для основної автентифікації в API GitHub


127

За допомогою CURL ми можемо передати ім'я користувача з веб-запитом HTTP таким чином:

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

-uПрапор приймає ім'я користувача для аутентифікації, а потім Curl буде запитувати пароль. Приклад CURL призначений для базової аутентифікації з GitHub Api .

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


$ pair має бути $pair = "$($user):$($pass)"Перевір затверджену відповідь. Я використовував вище, і це доставило мені біль
Bhavjot

Жодне з рішень, які пропонують -Credentialпідхід працювати, як правильний заголовок автентичності, не створюється при запиті.
StingyJack

@Shaun Luttin - Це питання ..... та сайт відповідей, а не сайт із запитаннями. Цей користувач вважає за краще бачити короткий запит та відповіді, окрім тих, що працювали у вашій конкретній ситуації, але не потрібно це читати двічі (один раз у редагованому запитанні, тепер приходьте QuestionAnswer, а потім знову у відповідях). Якщо занепокоєння було відповіддю, яке допомогло вам не бути найближчим до питання, StackExchange має функціонал, щоб максимально наблизити відповідь до максимально можливого питання.
user66001

1
@ user66001 Дякую за відгук. Я перемістив свою відповідь-запитання до власної відповіді для подальшого ознайомлення. Я думаю, це поліпшення.
Шон Луттин

@ShaunLuttin - Чудова ідея! :)
user66001

Відповіді:


147

Я припускаю базову автентифікацію тут.

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

Ви можете отримати свої дані за допомогою інших засобів ( Import-Clixmlтощо), але це має бути [PSCredential]об'єктом.

Редагувати на основі коментарів:

GitHub порушує RFC, як вони пояснюють у наданому вами посиланні :

API підтримує базову автентифікацію, як визначено в RFC2617, з кількома незначними відмінностями. Основна відмінність полягає в тому, що RFC вимагає відповіді на неавторизовані запити за допомогою 401 несанкціонованих відповідей. У багатьох місцях це свідчить про існування даних користувачів. Натомість API GitHub відповідає 404 Not Found. Це може спричинити проблеми для HTTP-бібліотек, які передбачають 401 несанкціоновану відповідь. Рішення полягає в ручному створенні заголовка авторизації.

Наскільки 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

Ви можете поєднати деякі конкатенації рядків, але я хотів розбити це, щоб зробити його більш зрозумілим.


1
Як я вже говорив, це працює для базової аутентифікації, але я не знаю, який тип аутентифікації використовує API GitHub. Ви можете опублікувати детальну інформацію про те, що очікується, і це може допомогти нам вирішити проблему.
британіст

1
А, здається, GitHub (за власним визнанням) не слідкує за RFC, але Powershell є. Я відредагував відповідь з додатковою інформацією та способом вирішення.
британіст

1
Так, якщо ви збираєтеся робити багато подібних дзвінків, я рекомендую ввести це у функції. Як я вже говорив, я дійсно розрізав усі деталі для наочності, але ви могли це зробити за один рядок (це було б просто безладно).
британіст

1
@Aref, ви можете опублікувати нове запитання з використанням коду. Якщо ви зробите це, і дайте мені знати, я погляну.
британіст

1
Вам потрібно буде вручну скласти заголовки, якщо намагатиметесь перевірити автентифікацію і проти API REST Visual Studio Team Services
Brent Robinson,

44

Використовуй це:

$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

Чомусь обрана відповідь не працювала для мене під час використання її на TFS vNext, але ця зробила трюк. Дуже дякую!
Тибс

Вибрана відповідь не спрацювала для запуску робочої книги з власною оболонкою на лазерному русі для ініціювання запущеної роботи, але ця відповідь спрацювала.
Сем

7

Мені довелося це зробити, щоб він працював:

$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

6

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


5

Якщо комусь знадобиться один лайнер:

iwr -Uri 'https://api.github.com/user' -Headers @{ Authorization = "Basic "+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("user:pass")) }

2

інший спосіб - використовувати certutil.exe зберегти своє ім’я користувача та пароль у файлі, наприклад in.txt як ім'я користувача: пароль

certutil -encode in.txt out.txt

Тепер ви повинні мати можливість використовувати значення автентифікації з out.txt

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

2

Я знаю, що це трохи від оригінального запиту ОП, але я натрапив на це, шукаючи спосіб використовувати Invoke-WebRequest щодо сайту, що вимагає базової автентифікації.

Різниця в тому, що я не хотів записувати пароль у сценарії. Натомість я хотів підказати бігу сценарію для отримання облікових даних для сайту.

Ось як я впорався

$creds = Get-Credential

$basicCreds = [pscredential]::new($Creds.UserName,$Creds.Password)

Invoke-WebRequest -Uri $URL -Credential $basicCreds

У результаті виходить, що для запуску сценарію запропоновано діалогове вікно входу для U / P, тоді Invoke-WebRequest зможе отримати доступ до сайту за допомогою цих даних. Це працює, тому що $ Creds.Password - це вже зашифрований рядок.

Я сподіваюся, що це допоможе комусь, хто шукає подібне рішення вищезазначеного питання, але не зберігаючи ім'я користувача або PW у сценарії


0

Це те, що працювало для нашої конкретної ситуації.

Примітки - з Вікіпедії на Basic Auth з боку клієнта . Дякую за відповідь @ briantist за допомогу!

Об'єднайте ім'я користувача та пароль в одну рядок username:password

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

Кодуйте рядок до варіанту RFC2045-MIME Base64, за винятком обмежень 76 знаків / рядок.

$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

Версія PowerShell цього є більш багатослівною, ніж версія CURL. Чому так? @briantist зазначив, що GitHub порушує RFC і PowerShell дотримується цього. Чи означає це, що cURL також порушує стандарт?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.