$ curl -u <your_username> https://api.github.com/user
-u
标志接受用户名进行身份验证,然后cURL将请求密码。该cURL示例适用于使用GitHub Api进行基本身份验证。
我们如何类似地通过Invoke-WebRequest传递用户名和密码?最终目标是在GitHub API中使用PowerShell进行基本身份验证。
$ curl -u <your_username> https://api.github.com/user
-u
标志接受用户名进行身份验证,然后cURL将请求密码。该cURL示例适用于使用GitHub Api进行基本身份验证。
我们如何类似地通过Invoke-WebRequest传递用户名和密码?最终目标是在GitHub API中使用PowerShell进行基本身份验证。
我在这里假设使用基本身份验证。
$cred = Get-Credential
Invoke-WebRequest -Uri 'https://whatever' -Credential $cred
您可以通过其他方式(Import-Clixml
等)获取凭据,但它必须是一个[PSCredential]
对象。
Github正在违反RFC规范,如他们在您提供的链接中所解释的:
API支持基本认证(Basic Authentication),如RFC2617所定义的,但有一些细微差别。主要区别是RFC要求未经身份验证的请求应以401未授权响应进行回答。在许多地方,这将披露用户数据的存在。相反,GitHub API响应为404未找到。这可能会对假定401未经授权响应的HTTP库造成问题。解决方法是手动制作Authorization标头。
就我所知,Powershell的Invoke-WebRequest
会等待401响应再发送凭据,而由于GitHub从未提供401响应,因此您的凭据永远不会被发送。
相反,您需要自己创建基本认证标头。
基本认证接受一个字符串,该字符串由用户名和密码用冒号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
你可以将一些字符串连接起来,但我想将其拆开以使其更清晰。使用这个:
$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
如果有人需要一句话简述:
iwr -Uri 'https://api.github.com/user' -Headers @{ Authorization = "Basic "+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("user:pass")) }
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 中测试。
credential
提供用户和密码,那么基本授权头是否必要?根据您的回答,-credential
只有在从headers
获得401
之后才能工作,因此必须有basic foo:bar
以避免匿名。 - Timofoo:bar
是正确的,我需要将其操作为例如 foobar:bar
用于 auth header key
。 - Timofoo:bar
,那么你需要使用其他的东西。 - Leonard Brünings我必须这样做才能使它工作:
$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
这里有另一种使用WebRequest的方法,我希望它能对你有用。
$user = 'whatever'
$pass = 'whatever'
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)
$headers = @{ Authorization = "Basic Zm9vOmJhcg==" }
Invoke-WebRequest -Credential $credential -Headers $headers -Uri "https://dc01.test.local/"
-Headers
参数需要一个 [string],[string]
的字典或哈希表。实际上你可以直接定义一个数组 - 例如 @(Authorization = 'Basic ...')
像他在这里所做的一样,PowerShell 将为您进行类型转换。 - Kellen Stuartbasic
和 digest
混淆,这个答案中使用了 credential
参数。 - Timousername: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)
Method Base64String
。$basicAuthValue = "Basic $base64"
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
。$headers = @{ Authorization = $basicAuthValue }
调用Web请求
Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers
我知道这有点偏离原始请求,但我在寻找一种使用Invoke-WebRequest对需要基本身份验证的站点进行操作的方法时遇到了这个问题。
区别在于,我不想在脚本中记录密码。相反,我想提示脚本运行者为该站点输入凭据。
以下是我处理方法:
$creds = Get-Credential
$basicCreds = [pscredential]::new($Creds.UserName,$Creds.Password)
Invoke-WebRequest -Uri $URL -Credential $basicCreds
certutil -encode in.txt out.txt
$headers = @{ Authorization = "Basic $((get-content out.txt)[1])" }
Invoke-WebRequest -Uri 'https://whatever' -Headers $Headers
$pair = "$($user):$($pass)"
。请查看已批准的答案。我之前使用上述代码时遇到了很多问题。 - Bhavjot-Credential
方法的解决方案能够正常工作,因为在发出请求时并没有生成正确的身份验证标头。 - StingyJackcurl
中,我必须使用参数--anyauth
才能使用用户名/密码。否则会出现权限错误。 - Timo