Gunakan Invoke-WebRequest dengan nama pengguna dan sandi untuk otentikasi dasar di GitHub API

127

Dengan cURL, kita dapat mengirimkan nama pengguna dengan permintaan web HTTP sebagai berikut:

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

The -ubendera menerima nama pengguna untuk otentikasi, dan kemudian cURL akan meminta password. Contoh cURL adalah untuk otentikasi dasar dengan GitHub Api .

Bagaimana kita juga memberikan nama pengguna dan kata sandi bersama dengan Invoke-WebRequest? Tujuan utamanya adalah untuk menggunakan PowerShell dengan otentikasi Dasar di GitHub API.

Shaun Luttin
sumber
$ pair harus $pair = "$($user):$($pass)"Periksa jawaban yang disetujui. Saya menggunakan cara di atas dan itu memberi saya terlalu banyak rasa sakit
Bhavjot
Tak satu pun dari solusi yang menyarankan -Credentialpendekatan tersebut berfungsi karena header autentikasi yang benar tidak dibuat saat permintaan dibuat.
StingyJack
@Shaun Luttin - Ini adalah situs tanya ..... dan jawab, bukan situs Tanya Jawab. Pengguna yang satu ini lebih suka melihat pertanyaan dan jawaban sesingkat mungkin selain yang berhasil untuk situasi khusus Anda, tetapi tidak harus membacanya dua kali (sekali dalam Pertanyaan yang diedit, sekarang munculkan QuestionAnswer, dan kemudian lagi dalam jawaban). Jika perhatiannya adalah jawaban yang tidak akan membantu Anda paling dekat dengan pertanyaan, StackExchange memiliki fungsionalitas untuk menghadirkan jawaban terbaik / yang diterima sedekat mungkin dengan pertanyaan.
pengguna66001
1
@ user66001 Terima kasih atas umpan baliknya. Saya telah memindahkan jawaban dalam pertanyaan saya ke jawabannya sendiri untuk referensi nanti. Saya pikir ini adalah peningkatan.
Shaun Luttin
@ShaunLuttin - Ide bagus! :)
pengguna66001

Jawaban:

147

Saya mengasumsikan otentikasi dasar di sini.

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

Anda bisa mendapatkan kredensial Anda melalui cara lain ( Import-Clixml, dll.), Tetapi kredensial harus berupa [PSCredential]objek.

Edit berdasarkan komentar:

GitHub melanggar RFC seperti yang mereka jelaskan di tautan yang Anda berikan :

API mendukung Otentikasi Dasar seperti yang didefinisikan dalam RFC2617 dengan sedikit perbedaan. Perbedaan utamanya adalah bahwa RFC membutuhkan permintaan yang tidak diautentikasi untuk dijawab dengan tanggapan 401 Tidak Sah. Di banyak tempat, ini akan mengungkap keberadaan data pengguna. Sebagai gantinya, GitHub API merespons dengan 404 Not Found. Ini dapat menyebabkan masalah untuk pustaka HTTP yang mengasumsikan respons 401 Tidak Sah. Solusinya adalah membuat header Otorisasi secara manual.

Sepengetahuan saya, Powershell Invoke-WebRequestharus menunggu respons 401 sebelum mengirim kredensial, dan karena GitHub tidak pernah menyediakannya, kredensial Anda tidak akan pernah dikirim.

Buat header secara manual

Sebagai gantinya, Anda harus membuat sendiri header autentikasi dasar.

Otentikasi dasar mengambil string yang terdiri dari nama pengguna dan kata sandi yang dipisahkan oleh titik dua user:passdan kemudian mengirimkan hasil yang dikodekan Base64 itu.

Kode seperti ini seharusnya berfungsi:

$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

Anda dapat menggabungkan beberapa rangkaian string tetapi saya ingin memecahnya agar lebih jelas.

briantist
sumber
1
Seperti yang saya katakan, ini berfungsi untuk otentikasi Dasar, tetapi saya tidak tahu jenis otentikasi apa yang digunakan API GitHub. Anda dapat memposting beberapa detail tentang apa yang diharapkan dan yang dapat membantu kami menyelesaikan masalah.
briantist
1
Ah, tampaknya GitHub (menurut pengakuan mereka sendiri) tidak mengikuti RFC, tetapi Powershell mengikuti. Saya telah mengedit jawabannya dengan lebih banyak informasi dan solusi.
briantist
1
Ya, jika Anda akan melakukan banyak panggilan semacam ini, saya sarankan untuk menggabungkan ini dalam sebuah fungsi. Seperti yang saya katakan, saya benar-benar memecahkan semua bagian untuk kejelasan, tetapi Anda dapat melakukan semuanya dalam satu baris (hanya akan berantakan).
briantist
1
@Aref, Anda harus memposting pertanyaan baru dengan kode yang Anda gunakan. Jika Anda melakukannya dan beri tahu saya tentang saya, saya akan memeriksanya.
briantist
1
Anda harus membuat header secara manual jika mencoba melakukan otentikasi terhadap API REST Layanan Tim Visual Studio juga
Brent Robinson
44

Gunakan ini:

$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
mfralou.dll
sumber
Untuk beberapa alasan jawaban yang dipilih tidak berhasil untuk saya saat menggunakannya di TFS vNext, tetapi yang ini berhasil. Terima kasih banyak!
Tybs
Jawaban yang dipilih tidak berfungsi untuk menjalankan runbook PowerShell di biru langit untuk memulai pekerjaan yang dipicu, tetapi jawaban ini berhasil.
Sam
7

Saya harus melakukan ini agar berhasil:

$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
livy111
sumber
6

Invoke-WebRequestmengikuti RFC2617 sebagai @briantist mencatat, namun ada beberapa sistem (misalnya JFrog Artifactory) yang memungkinkan penggunaan anonim jika Authorizationheader tidak ada, tetapi akan merespons 401 Forbiddenjika header berisi kredensial yang tidak valid.

Ini dapat digunakan untuk memicu 401 Forbiddenrespons dan mulai -Credentialsbekerja.

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

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

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

Ini akan mengirim tajuk yang tidak valid untuk pertama kalinya, yang akan diganti dengan kredensial yang valid dalam permintaan kedua karena -Credentialsmenimpa Authorizationtajuk.

Diuji dengan Powershell 5.1

Leonard Brünings
sumber
5

Jika seseorang membutuhkan satu liner:

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

cara lain adalah dengan menggunakan certutil.exe simpan nama pengguna dan kata sandi Anda di file misalnya in.txt sebagai nama pengguna: kata sandi

certutil -encode in.txt out.txt

Sekarang Anda seharusnya dapat menggunakan nilai auth dari out.txt

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

Saya tahu ini sedikit dari permintaan asli OP tetapi saya menemukan ini saat mencari cara untuk menggunakan Invoke-WebRequest terhadap situs yang membutuhkan otentikasi dasar.

Bedanya, saya tidak ingin mencatat kata sandi di skrip. Sebaliknya, saya ingin meminta kredensial untuk situs tersebut kepada pelari skrip.

Begini cara saya menanganinya

$creds = Get-Credential

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

Invoke-WebRequest -Uri $URL -Credential $basicCreds

Hasilnya adalah runner skrip diminta dengan dialog login untuk U / P, kemudian Invoke-WebRequest dapat mengakses situs dengan kredensial tersebut. Ini berfungsi karena $ Creds.Password sudah menjadi string terenkripsi.

Saya harap ini membantu seseorang yang mencari solusi serupa untuk pertanyaan di atas tetapi tanpa menyimpan nama pengguna atau PW di skrip

Ernest Correale
sumber
0

Inilah yang berhasil untuk situasi khusus kami.

Catatan berasal dari Wikipedia tentang Basic Auth dari Sisi Klien . Terima kasih untuk jawaban @ briantist atas bantuannya!

Gabungkan nama pengguna dan kata sandi menjadi satu string username:password

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

Enkode string ke varian RFC2045-MIME dari Base64, kecuali tidak terbatas pada 76 karakter / baris.

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

Buat nilai Auth sebagai metode, spasi, lalu pasangan yang dikodekan Method Base64String

$basicAuthValue = "Basic $base64"

Buat tajuk Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

$headers = @{ Authorization = $basicAuthValue }

Panggil permintaan web

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

Versi PowerShell ini lebih bertele-tele daripada versi cURL. Mengapa demikian? @briantist menunjukkan bahwa GitHub melanggar RFC dan PowerShell berpegang teguh padanya. Apakah itu berarti cURL juga melanggar standar?

Shaun Luttin
sumber