web-dev-qa-db-ja.com

GitHub APIの基本認証にユーザー名とパスワードを指定してInvoke-WebRequestを使用する

最初の質問

CURLを使うと、次のようにHTTP Webリクエストでユーザー名を渡すことができます。

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

-uフラグは認証のためにユーザー名を受け入れ、それからcURLはパスワードを要求します。 cURLの例は GitHub Apiによる基本認証 です。

Invoke-WebRequestと同様に、ユーザー名とパスワードをどのように渡しますか?最終的な目標は、GitHub APIの基本認証でPowerShellを使用することです。

編集(これはうまくいったことです)

メモは クライアントサイドからの基本認証に関するウィキペディア からのものです。

ユーザー名とパスワードを1つの文字列にまとめますusername:password

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

76文字/行に限定されない場合を除き、文字列をBase64のRFC2045-MIME形式にエンコードします。

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

メソッドとしてAuth値、スペース、次にエンコードされたペアを作成しますMethod Base64String

$basicAuthValue = "Basic $base64"

ヘッダAuthorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==を作成します

$headers = @{ Authorization = $basicAuthValue }

Webリクエストを呼び出す

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

助けてくれてありがとう。

討論

これのPowerShellバージョンは、cURLバージョンよりも冗長です。何故ですか? @briantistは、GitHubがRFCを破り、PowerShellがそれにこだわっていると指摘しました。それは、cURLも標準規格に違反しているということですか?

96
Shaun Luttin

ここでは基本認証を想定しています。

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

あなたは他の方法(Import-Clixmlなど)を通してあなたの資格を得ることができますが、それは[PSCredential]オブジェクトでなければなりません。

コメントに基づいて編集します。

GitHubはあなたが提供した リンクで説明されているようにRFCを壊しています

APIは、RFC 2617で定義されている基本認証をサポートしていますが、若干の違いがあります。主な違いは、RFCでは、認証されていない要求に401のUnauthorized応答で応答することを要求していることです。多くの場所で、これはユーザーデータの存在を開示するでしょう。代わりに、GitHub APIは404 Not Foundで応答します。これは401 Unauthorizedレスポンスを想定しているHTTPライブラリに問題を引き起こすかもしれません。解決策は、Authorizationヘッダーを手動で作成することです。

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

あなたは文字列の連結のいくつかを組み合わせることができますが、私はそれをより明確にするためにそれを分割したいと思いました。

107
briantist

これを使って:

$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
32
mfralou

@ briantistが述べたようにInvoke-WebRequestはRFC2617に従いますが、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 "..."

-CredentialsAuthorizationヘッダーをオーバーライドするため、これは無効なヘッダーを最初に送信します。これは2番目の要求で有効な資格情報に置き換えられます。

Powershell 5.1でテスト済み

5

別の方法は、certutil.exeを使用して、ユーザー名とパスワードをファイルに保存することです。ユーザー名としてのin.txt:パスワード

certutil -encode in.txt out.txt

これでout.txtのauth値を使えるようになるはずです。

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

私はそれを機能させるためにこれをしなければなりませんでした:

$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
1
livy111