powershell - Use Invoke-WebRequest con un nombre de usuario y contraseña para la autenticación básica en la API de GitHub
github-api http-basic-authentication (5)
Estoy asumiendo la autenticación básica aquí.
$cred = Get-Credential
Invoke-WebRequest -Uri ''https://whatever'' -Credential $cred
Puede obtener su credencial a través de otros medios (
Import-Clixml
, etc.), pero tiene que ser un objeto
[PSCredential]
.
Editar basado en comentarios:
GitHub está rompiendo RFC como explican en el enlace que proporcionó :
La API admite la autenticación básica como se define en RFC2617 con algunas pequeñas diferencias. La principal diferencia es que el RFC requiere que las solicitudes no autenticadas sean respondidas con 401 respuestas no autorizadas. En muchos lugares, esto revelaría la existencia de datos del usuario. En cambio, la API de GitHub responde con 404 No encontrado. Esto puede causar problemas para las bibliotecas HTTP que asumen una respuesta no autorizada 401. La solución es crear manualmente el encabezado de autorización.
Invoke-WebRequest
, que yo sepa, espera una respuesta 401 antes de enviar las credenciales, y dado que GitHub nunca proporciona una, sus credenciales nunca serán enviadas.
Construir manualmente los encabezados
En su lugar, tendrá que crear los encabezados de autenticación básicos usted mismo.
La autenticación básica toma una cadena que consiste en el nombre de usuario y la contraseña separados por un
user:pass
dos puntos
user:pass
y luego envía el resultado codificado en Base64 de eso.
Un código como este debería funcionar:
$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
Podrías combinar algunas de las concatenaciones de cuerdas, pero quería separarlas para aclararlas.
Pregunta inicial
Con cURL, podemos pasar un nombre de usuario con una solicitud web HTTP de la siguiente manera:
$ curl -u <your_username> https://api.github.com/user
El indicador
-u
acepta un nombre de usuario para la autenticación y luego cURL solicitará la contraseña.
El ejemplo de cURL es para la
autenticación básica con la API de GitHub
.
¿Cómo pasamos de manera similar un nombre de usuario y contraseña junto con Invoke-WebRequest? El objetivo final es usar PowerShell con autenticación básica en la API de GitHub.
Editar (Esto es lo que funcionó)
Las notas son de Wikipedia sobre autenticación básica del lado del cliente .
Combine el nombre de usuario y la contraseña en un solo
username:password
cadena
username:password
$user = "shaunluttin"
$pass = "super-strong-alpha-numeric-symbolic-long-password"
$pair = "${user}:${pass}"
Codifique la cadena a la variante RFC2045-MIME de Base64, excepto que no se limita a 76 caracteres / línea.
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
Cree el valor Auth como método, un espacio y luego el par codificado
Method Base64String
$basicAuthValue = "Basic $base64"
Crear el encabezado
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
$headers = @{ Authorization = $basicAuthValue }
Invocar la solicitud web
Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers
¡Gracias a @briantist por la ayuda!
Discusión
La versión de PowerShell de esto es más detallada que la versión cURL. ¿Porqué es eso? @briantist señaló que GitHub está rompiendo el RFC y PowerShell se apega a él. ¿Eso significa que cURL también está rompiendo con el estándar?
Tuve que hacer esto para que funcione:
$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
Utilizar este:
$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
otra forma es usar certutil.exe, guarde su nombre de usuario y contraseña en un archivo, por ejemplo, in.txt como nombre de usuario: contraseña
certutil -encode in.txt out.txt
Ahora debería poder usar el valor de autenticación de out.txt
$headers = @{ Authorization = "Basic $((get-content out.txt)[1])" }
Invoke-WebRequest -Uri ''https://whatever'' -Headers $Headers
Invoke-WebRequest
sigue el RFC2617 como señaló @briantist, sin embargo, hay algunos sistemas (por ejemplo, JFrog Artifactory) que permiten el uso anónimo si el encabezado de
Authorization
está ausente, pero responderá con
401 Forbidden
si el encabezado contiene credenciales no válidas.
Esto se puede utilizar para activar la respuesta
401 Forbidden
y hacer que las
-Credentials
funcionen.
$login = Get-Credential -Message "Enter Credentials for Artifactory"
#Basic foo:bar
$headers = @{ Authorization = "Basic Zm9vOmJhcg==" }
Invoke-WebRequest -Credential $login -Headers $headers -Uri "..."
Esto enviará el encabezado no válido la primera vez, que se reemplazará con las credenciales válidas en la segunda solicitud ya que
-Credentials
anula el encabezado de
Authorization
.
Probado con Powershell 5.1