ใช้ Invoke-WebRequest ด้วยชื่อผู้ใช้และรหัสผ่านสำหรับการพิสูจน์ตัวตนพื้นฐานบน GitHub API


127

ด้วย cURL เราสามารถส่งชื่อผู้ใช้ด้วยคำขอเว็บ HTTP ได้ดังนี้:

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

-uธงยอมรับชื่อผู้ใช้สำหรับการตรวจสอบแล้วม้วนจะขอรหัสผ่าน ตัวอย่างม้วนสำหรับการตรวจสอบเบื้องต้นกับ GitHub Api

เราจะส่งชื่อผู้ใช้และรหัสผ่านพร้อมกับ Invoke-WebRequest ได้อย่างไร? เป้าหมายสูงสุดคือผู้ใช้ PowerShell ที่มีการรับรองความถูกต้องขั้นพื้นฐานใน GitHub API


$ pair ควร$pair = "$($user):$($pass)"ตรวจสอบคำตอบที่ได้รับอนุมัติ ฉันใช้ข้างต้นและมันทำให้ฉันเจ็บปวดมากเกินไป
Bhavjot

ไม่มีโซลูชันใดที่แนะนำ-Credentialวิธีการทำงานเนื่องจากไม่ได้สร้างส่วนหัวการตรวจสอบสิทธิ์ที่ถูกต้องเมื่อมีการร้องขอ
StingyJack

@ Shaun Luttin - นี่คือคำถาม ..... และไซต์คำตอบไม่ใช่ไซต์ตอบคำถาม ผู้ใช้รายนี้ต้องการเห็นคำถามและคำตอบที่กระชับที่สุดเท่าที่จะเป็นไปได้นอกเหนือจากสิ่งที่ใช้ได้ผลกับสถานการณ์เฉพาะของคุณ แต่ไม่จำเป็นต้องอ่านซ้ำสองครั้ง (เมื่ออยู่ในคำถามที่แก้ไขแล้วให้มาที่ QuestionAnswer และตอบคำถามอีกครั้ง) หากข้อกังวลคือคำตอบที่ช่วยให้คุณไม่ใกล้เคียงกับคำถามมากที่สุด StackExchange มีฟังก์ชันเพื่อให้คำตอบที่ดีที่สุด / เป็นที่ยอมรับใกล้เคียงกับคำถามมากที่สุด
user66001

1
@ user66001 ขอบคุณสำหรับคำติชม ฉันได้ย้ายคำตอบในคำถามไปยังคำตอบของตัวเองเพื่อใช้อ้างอิงในภายหลัง ฉันคิดว่านี่คือการปรับปรุง
Shaun Luttin

@ShaunLuttin - ความคิดที่ดี! :)
user66001

คำตอบ:


147

ฉันสมมติว่ามีการรับรองความถูกต้องขั้นพื้นฐานที่นี่

$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

คุณสามารถรวมการต่อสตริงบางส่วนได้ แต่ฉันต้องการแยกมันออกเพื่อให้ชัดเจนขึ้น


1
อย่างที่บอกว่าใช้ได้กับการพิสูจน์ตัวตนขั้นพื้นฐาน แต่ฉันไม่รู้ว่า GitHub API ใช้การตรวจสอบสิทธิ์แบบไหน คุณสามารถโพสต์รายละเอียดเกี่ยวกับสิ่งที่คาดหวังและอาจช่วยเราแก้ปัญหาได้
briantist

1
อาดูเหมือนว่า GitHub (โดยการยอมรับของตนเอง) ไม่ได้ติดตาม RFC แต่ Powershell คือ ฉันได้แก้ไขคำตอบพร้อมข้อมูลเพิ่มเติมและวิธีแก้ปัญหาชั่วคราว
briantist

1
ใช่ถ้าคุณจะโทรประเภทนี้หลายครั้งฉันขอแนะนำให้รวมฟังก์ชันนี้ไว้ในฟังก์ชัน อย่างที่ฉันบอกว่าฉันแยกชิ้นส่วนทั้งหมดออกมาเพื่อความชัดเจน แต่คุณสามารถทำมันทั้งหมดในบรรทัดเดียว (มันจะยุ่ง)
briantist

1
@Aref คุณควรโพสต์คำถามใหม่พร้อมรหัสที่คุณใช้ ถ้าคุณทำเช่นนั้นและแจ้งให้เราทราบเราจะตรวจสอบ
briantist

1
คุณจะต้องสร้างส่วนหัวด้วยตนเองหากพยายามตรวจสอบสิทธิ์กับ Visual Studio Team Services REST API ด้วย
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 แต่คำตอบนี้ใช้เคล็ดลับ ขอบคุณมาก!
Tybs

คำตอบที่เลือกใช้ไม่ได้กับการเรียกใช้ powershell runbook บน azure เพื่อเริ่มงานที่ทริกเกอร์ แต่คำตอบนี้ใช้งานได้
แซม

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

ตอนนี้คุณควรจะสามารถใช้ค่า auth จาก out.txt

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

2

ฉันรู้ว่านี่เป็นเพียงคำขอดั้งเดิมของ OPs แต่ฉันเจอสิ่งนี้ในขณะที่กำลังมองหาวิธีใช้ 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

นี่คือสิ่งที่ใช้ได้กับสถานการณ์เฉพาะของเรา

หมายเหตุจากวิกิพีเดียตรวจสอบสิทธิ์พื้นฐานจากฝั่งไคลเอ็นต์ ขอบคุณคำตอบของ @ 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 ทำลายมาตรฐานด้วยหรือไม่?

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.