使用cURL,我们可以通过HTTP Web请求传递用户名,如下所示:
$ curl -u <your_username> https://api.github.com/user
-u
标志接受用于身份验证的用户名,然后cURL将请求密码。 cURL示例适用于Basic authentication with the GitHub Api。
我们如何同样传递用户名和密码以及Invoke-WebRequest?最终目标是在GitHub API中使用基本身份验证的PowerShell。
备注来自Wikipedia on Basic Auth from the Client Side。
将用户名和密码合并为一个字符串username:password
$user = "shaunluttin"
$pass = "super-strong-alpha-numeric-symbolic-long-password"
$pair = "${user}:${pass}"
将字符串编码为Base64的RFC2045-MIME变体,但不限于76个字符/行。
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
创建Auth值作为方法,空格,然后编码对Method Base64String
$basicAuthValue = "Basic $base64"
创建标题Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
$headers = @{ Authorization = $basicAuthValue }
调用网络请求
Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers
感谢@briantist的帮助!
PowerShell版本比cURL版本更冗长。这是为什么? @briantist指出GitHub打破了RFC并且PowerShell坚持使用它。这是否意味着cURL也打破了标准?
答案 0 :(得分:105)
我在这里假设基本身份验证。
$cred = Get-Credential
Invoke-WebRequest -Uri 'https://whatever' -Credential $cred
您可以通过其他方式(Import-Clixml
等)获取您的凭据,但它必须是[PSCredential]
对象。
GitHub正在破解RFC,因为他们在link you provided中解释:
API支持RFC2617中定义的基本身份验证 细微差别。主要区别在于RFC要求 401未经授权的未经认证的请求 响应。在许多地方,这将披露用户的存在 数据。相反,GitHub API以404 Not Found响应。这可能 假定401未授权的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
你可以结合一些字符串连接,但我想将其分解以使其更清晰。
答案 1 :(得分:32)
使用此:
configure
set service dns forwarding options address=/.bing.com/216.239.38.120
set service dns forwarding options address=/.ask.com/216.239.38.120
set service dns forwarding options address=/.duckduckgo.com/216.239.38.120
commit
save
答案 2 :(得分:5)
Invoke-WebRequest
遵循RFC2617,但有些系统(例如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进行测试
答案 3 :(得分:5)
如果某人需要一根衬纸:
iwr -Uri 'https://api.github.com/user' -Headers @{ Authorization = "Basic "+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("user:pass")) }
答案 4 :(得分:2)
我知道这与OP的原始请求有点差,但是我在寻找一种针对需要基本身份验证的网站使用Invoke-WebRequest的方式时碰到了这一点。
区别在于,我不想在脚本中记录密码。相反,我想提示脚本运行者输入网站的凭据。
这是我的处理方式
$creds = Get-Credential
$basicCreds = [pscredential]::new($Creds.UserName,$Creds.Password)
Invoke-WebRequest -Uri $URL -Credential $basicCreds
结果是脚本运行器被提示输入U / P的登录对话框,然后Invoke-WebRequest可以使用这些凭据访问该站点。之所以可行,是因为$ Creds.Password已经是一个加密的字符串。
我希望这可以帮助寻求与上述问题类似的解决方案的人,但又不必在脚本中保存用户名或密码
答案 5 :(得分:2)
这是使用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/"
答案 6 :(得分:1)
我必须这样做才能使其正常工作:
$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
答案 7 :(得分:1)
这对我们的特定情况有效。
注释来自Wikipedia on Basic Auth from the Client Side。谢谢@briantist's answer的帮助!
将用户名和密码合并为一个字符串username:password
$user = "shaunluttin"
$pass = "super-strong-alpha-numeric-symbolic-long-password"
$pair = "${user}:${pass}"
将字符串编码为Base64的RFC2045-MIME变体,但不限于76个字符/行。
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
创建Auth值作为方法,空格,然后创建编码对Method Base64String
$basicAuthValue = "Basic $base64"
创建标题Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
$headers = @{ Authorization = $basicAuthValue }
调用网络请求
Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers
PowerShell版本比cURL版本更为冗长。这是为什么? @briantist指出GitHub违反了RFC,PowerShell坚持使用RFC。这是否意味着cURL也违反了标准?
答案 8 :(得分:0)
另一种方法是使用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