web-dev-qa-db-fra.com

Utilisez Invoke-WebRequest avec un nom d'utilisateur et un mot de passe pour l'authentification de base sur l'API GitHub

Question initiale

Avec cURL, nous pouvons passer un nom d'utilisateur avec une requête Web HTTP comme suit: 

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

L'indicateur -u accepte un nom d'utilisateur pour l'authentification, puis cURL demandera le mot de passe. L'exemple cURL concerne l'authentification Basic avec GitHub Api .

Comment pouvons-nous également transmettre un nom d'utilisateur et un mot de passe avec Invoke-WebRequest? Le but ultime est d’utiliser PowerShell avec l’authentification de base dans l’API GitHub.

Modifier (c'est ce qui a fonctionné)

Les notes proviennent de Wikipedia sur l’authentification de base du côté client .

Combinez le nom d'utilisateur et le mot de passe en une seule chaîne username:password

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

Encodez la chaîne dans la variante RFC2045-MIME de Base64, sauf qu'elle ne soit pas limitée à 76 caractères/ligne.

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

Créez la valeur Auth en tant que méthode, un espace, puis la paire codée Method Base64String

$basicAuthValue = "Basic $base64"

Créez l'en-tête Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

$headers = @{ Authorization = $basicAuthValue }

Invoquer la requête web

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

Merci à @briantist pour l'aide!

Discussion

La version de PowerShell est plus détaillée que la version de cURL. Pourquoi donc? @briantist a souligné que GitHub rompait le RFC et que PowerShell s'y tenait. Cela signifie-t-il que cURL est également en rupture avec la norme?

86
Shaun Luttin

J'assume l'authentification de base ici.

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

Vous pouvez obtenir vos informations d'identification par d'autres moyens (Import-Clixml, etc.), mais il doit s'agir d'un objet [PSCredential].

Modifier en fonction des commentaires:

GitHub rompt RFC comme ils l'expliquent dans le lien que vous avez fourni :

L'API prend en charge l'authentification de base telle que définie dans la RFC2617 avec quelques légères différences. La principale différence est que la RFC requiert Les demandes non authentifiées doivent être traitées avec 401 Unauthorized les réponses. Dans de nombreux endroits, cela révélerait l'existence d'un utilisateur Les données. Au lieu de cela, l'API GitHub répond par 404 Introuvables. Ceci peut poser des problèmes pour les bibliothèques HTTP qui supposent un .1 .1. non autorisé. réponse. La solution consiste à créer manuellement l'en-tête Authorization.

À ma connaissance, le Invoke-WebRequest de Powershell attend une réponse 401 avant d'envoyer les informations d'identification, et comme GitHub n'en fournit jamais, vos informations d'identification ne seront jamais envoyées.

Construire manuellement les en-têtes

Au lieu de cela, vous devrez créer vous-même les en-têtes d'authentification de base.

L'authentification de base prend une chaîne composée du nom d'utilisateur et du mot de passe séparés par un signe deux-points user:pass, puis envoie le résultat codé en Base64 de cette dernière.

Un code comme celui-ci devrait fonctionner:

$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

Vous pouvez combiner une partie de la concaténation de chaînes mais je voulais la clarifier pour la rendre plus claire.

96
briantist

Utilisez ceci: 

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

Invoke-WebRequest suit le RFC2617 comme @briantist l'a noté, mais certains systèmes (par exemple, JFrog Artifactory) autorisent l'utilisation anonyme si l'en-tête Authorization est absent, mais répondent avec 401 Forbidden si l'en-tête contient des informations d'identification non valides.

Ceci peut être utilisé pour déclencher la réponse 401 Forbidden et faire fonctionner -Credentials.

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

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

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

Cela enverra la première fois l'en-tête non valide, qui sera remplacé par les informations d'identification valides dans la deuxième demande, car -Credentials remplace l'en-tête Authorization.

Testé avec Powershell 5.1

3
Leonard Brünings

une autre méthode consiste à utiliser certutil.exe Enregistrez votre nom d’utilisateur et votre mot de passe dans un fichier, par exemple. in.txt comme nom d'utilisateur: mot de passe

certutil -encode in.txt out.txt

Maintenant, vous devriez pouvoir utiliser la valeur d'authentification de out.txt

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

Je devais le faire pour que cela fonctionne:

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