Sử dụng Invoke-WebRequest với tên người dùng và mật khẩu để xác thực cơ bản trên API GitHub


127

Với cURL, chúng tôi có thể chuyển tên người dùng với yêu cầu web HTTP như sau:

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

Các -ucờ chấp nhận một tên người dùng để xác thực, và sau đó cURL sẽ yêu cầu mật khẩu. Ví dụ cURL dành cho xác thực Cơ bản với Apit GitHub .

Làm thế nào để chúng tôi tương tự vượt qua tên người dùng và mật khẩu cùng với Invoke-WebRequest? Mục tiêu cuối cùng là người dùng PowerShell với xác thực Cơ bản trong API GitHub.


$ cặp nên được $pair = "$($user):$($pass)"Kiểm tra câu trả lời đã được phê duyệt. Tôi đã sử dụng những thứ trên và nó mang lại cho tôi quá nhiều nỗi đau
Bhavjot

Không có giải pháp nào đề xuất -Credentialcách tiếp cận hoạt động như tiêu đề xác thực chính xác không được tạo khi yêu cầu được thực hiện.
StingyJack

@Shaun Luttin - Đây là một câu hỏi ..... và trang web trả lời, không phải là một trang web Trả lời câu hỏi. Người dùng này muốn xem một câu hỏi và câu trả lời ngắn gọn nhất có thể ngoài câu hỏi có hiệu quả cho tình huống cụ thể của bạn, nhưng không phải đọc hai lần (một lần trong Câu hỏi đã chỉnh sửa, bây giờ đến Câu hỏi trả lời, rồi lại trả lời). Nếu mối quan tâm là câu trả lời giúp bạn không phải là người gần gũi nhất với câu hỏi, StackExchange có chức năng mang câu trả lời tốt nhất / được chấp nhận đến mức gần nhất có thể để đặt câu hỏi.
user66001

1
@ user66001 Cảm ơn bạn đã phản hồi. Tôi đã chuyển câu trả lời của mình sang câu trả lời của riêng mình để tham khảo sau. Tôi nghĩ rằng đây là một cải tiến.
Shaun Luttin

@ShaunLuttin - Ý tưởng tuyệt vời! :)
user66001

Câu trả lời:


147

Tôi giả sử xác thực cơ bản ở đây.

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

Bạn có thể có được thông tin xác thực của mình thông qua các phương tiện khác ( Import-Clixml, v.v.), nhưng nó phải là một [PSCredential]đối tượng.

Chỉnh sửa dựa trên ý kiến:

GitHub đang phá vỡ RFC khi họ giải thích trong liên kết bạn cung cấp :

API hỗ trợ Xác thực cơ bản như được định nghĩa trong RFC2617 với một vài khác biệt nhỏ. Sự khác biệt chính là RFC yêu cầu các yêu cầu không được xác thực phải được trả lời với 401 phản hồi trái phép. Ở nhiều nơi, điều này sẽ tiết lộ sự tồn tại của dữ liệu người dùng. Thay vào đó, API GitHub phản hồi với 404 Không tìm thấy. Điều này có thể gây ra sự cố cho các thư viện HTTP giả sử phản hồi trái phép 401. Giải pháp là tự tạo thủ công Tiêu đề ủy quyền.

Invoke-WebRequestKiến thức của Powershell chờ đợi phản hồi của 401 trước khi gửi thông tin đăng nhập và vì GitHub không bao giờ cung cấp thông tin, thông tin đăng nhập của bạn sẽ không bao giờ được gửi.

Xây dựng thủ công

Thay vào đó, bạn sẽ phải tự tạo các tiêu đề xác thực cơ bản.

Xác thực cơ bản lấy một chuỗi bao gồm tên người dùng và mật khẩu được phân tách bằng dấu hai chấm user:passvà sau đó gửi kết quả được mã hóa Base64 của điều đó.

Mã như thế này sẽ hoạt động:

$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

Bạn có thể kết hợp một số nối chuỗi nhưng tôi muốn phá vỡ nó để làm cho nó rõ ràng hơn.


1
Như tôi đã nói, nó hoạt động cho xác thực Cơ bản, nhưng tôi không biết loại xác thực mà API GitHub sử dụng. Bạn có thể đăng một số chi tiết về những gì mong đợi và điều đó có thể giúp chúng tôi giải quyết vấn đề.
nghĩa quân phiệt

1
À, có vẻ như GitHub (bằng cách thừa nhận của chính họ) không theo RFC, nhưng Powershell thì có. Tôi đã chỉnh sửa câu trả lời với nhiều thông tin hơn và cách giải quyết.
nghĩa quân phiệt

1
Vâng, nếu bạn sẽ thực hiện nhiều cuộc gọi như vậy, tôi khuyên bạn nên thực hiện việc này trong một chức năng. Như tôi đã nói tôi thực sự đã phá vỡ tất cả các mảnh cho rõ ràng, nhưng bạn có thể làm tất cả trên một dòng (nó sẽ chỉ là lộn xộn).
nghĩa quân phiệt

1
@Aref, bạn nên đăng một câu hỏi mới với mã bạn đang sử dụng. Nếu bạn làm như vậy và cho tôi biết về tôi sẽ xem xét.
nghĩa quân phiệt

1
Bạn cũng sẽ cần xây dựng các tiêu đề theo cách thủ công nếu cố gắng xác thực với API REST của Visual Studio Team Services
Brent Robinson

44

Dùng cái này:

$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

Vì một số lý do, câu trả lời được chọn không phù hợp với tôi khi sử dụng nó trên TFS vNext, nhưng câu trả lời này đã làm được điều đó. Cảm ơn rất nhiều!
Tybs

Câu trả lời được chọn không hoạt động để chạy một cuốn sổ tay powershell trên azure để bắt đầu một công việc được kích hoạt nhưng câu trả lời này đã có hiệu quả.
Sam

7

Tôi đã phải làm điều này để làm cho nó hoạt động:

$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-WebRequesttheo RFC2617 như @briantist đã lưu ý, tuy nhiên, có một số hệ thống (ví dụ: JFrog Artifactory) cho phép sử dụng ẩn danh nếu Authorizationtiêu đề vắng mặt, nhưng sẽ phản hồi 401 Forbiddennếu tiêu đề chứa thông tin không hợp lệ.

Điều này có thể được sử dụng để kích hoạt 401 Forbiddenphản ứng và -Credentialslàm việc.

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

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

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

Điều này sẽ gửi tiêu đề không hợp lệ lần đầu tiên, sẽ được thay thế bằng thông tin xác thực hợp lệ trong yêu cầu thứ hai kể từ khi -Credentialsghi đè Authorizationtiêu đề.

Đã thử nghiệm với Powershell 5.1


5

Nếu ai đó sẽ cần một lớp lót:

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

2

một cách khác là sử dụng certutil.exe lưu tên người dùng và mật khẩu của bạn trong một tệp, ví dụ như in.txt làm tên người dùng: mật khẩu

certutil -encode in.txt out.txt

Bây giờ bạn sẽ có thể sử dụng giá trị auth từ out.txt

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

1

Tôi biết đây là một chút ngoài yêu cầu ban đầu của OP nhưng tôi đã gặp phải điều này trong khi tìm cách sử dụng Invoke-WebRequest đối với một trang web yêu cầu xác thực cơ bản.

Sự khác biệt là, tôi không muốn ghi lại mật khẩu trong tập lệnh. Thay vào đó, tôi muốn nhắc người chạy tập lệnh cho thông tin đăng nhập cho trang web.

Đây là cách tôi xử lý nó

$creds = Get-Credential

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

Invoke-WebRequest -Uri $URL -Credential $basicCreds

Kết quả là trình chạy tập lệnh được nhắc với hộp thoại đăng nhập cho U / P sau đó, Invoke-WebRequest có thể truy cập trang web với các thông tin đăng nhập đó. Điều này hoạt động vì $ Creds.Password đã là một chuỗi được mã hóa.

Tôi hy vọng điều này sẽ giúp ai đó tìm kiếm một giải pháp tương tự cho câu hỏi trên nhưng không lưu tên người dùng hoặc PW trong tập lệnh


0

Đây là những gì làm việc cho tình hình cụ thể của chúng tôi.

Ghi chú từ Wikipedia trên Auth cơ bản từ phía khách hàng . Cảm ơn câu trả lời của @ briantist vì sự giúp đỡ!

Kết hợp tên người dùng và mật khẩu thành một chuỗi username:password

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

Mã hóa chuỗi thành biến thể RFC2045-MIME của Base64, ngoại trừ không giới hạn ở 76 char / line.

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

Tạo giá trị Auth làm phương thức, khoảng trắng và sau đó là cặp được mã hóa Method Base64String

$basicAuthValue = "Basic $base64"

Tạo tiêu đề Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

$headers = @{ Authorization = $basicAuthValue }

Gọi yêu cầu web

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

Phiên bản PowerShell của phiên bản này dài hơn phiên bản cURL. Tại sao vậy? @briantist chỉ ra rằng GitHub đang phá vỡ RFC và PowerShell đang gắn bó với nó. Điều đó có nghĩa là cURL cũng đang phá vỡ với tiêu chuẩn?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.