PowerShell 的 Invoke-RestMethod 等效于 curl -u(基本身份验证)

Posted

技术标签:

【中文标题】PowerShell 的 Invoke-RestMethod 等效于 curl -u(基本身份验证)【英文标题】:PowerShell's Invoke-RestMethod equivalent of curl -u (Basic Authentication) 【发布时间】:2014-08-31 14:31:24 【问题描述】:

相当于什么

curl -u username:password ...

在 PowerShell 的 Invoke-RestMethod?我试过这个:

$securePwd = ConvertTo-SecureString "password" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($username, $securePwd)

Invoke-RestMethod -Credential $credential ...

但它返回 401,未经授权。

【问题讨论】:

阅读下面的 cmets 以及各种多线解决方案,这些解决方案在某些带有警告的情况下工作,让我感到难过的是,微软的 The One Great Scripting Language 有很多讨论,但没有简单的等价物,对于“curl -u 用户名:密码”。叹。我的解决方案是下载 curl.exe。 @pettys 是的,当然,很多咨询...顺便说一句 curl 包含在 Windows 中已经有一段时间了(不,不是豪华别名) 很高兴知道!我现在看到 curl.exe 已添加到 Win 10 build 17063 中的 C:\Windows\System32 中。@JaquelineVanek,我不确定您的所有评论该怎么做,但我很高兴知道它现在就在那里。 您是否尝试将 -Authentication Basic 作为参数添加到 Invoke-RestMethod ?其余的都是相同的,它对我来说很好。上下文:我正在从环境变量中提取信誉并查询 Zendesk HelpCenter API。 【参考方案1】:

这是迄今为止唯一对我有用的方法:

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("0:1" -f $username,$password)))

Invoke-RestMethod -Headers @Authorization=("Basic 0" -f $base64AuthInfo) ...

但我不相信没有更好的方法。

【讨论】:

在将 GetBytes 参数简化为 '("username:password")' 后为我们工作。谢谢!【参考方案2】:

我不确定为什么 -Credential 参数在您的情况下不起作用,但它适用于 httpbin service。

你可以试试这个:

$pwd = ConvertTo-SecureString "MyPassword" -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ('PsUser', $pwd)

Invoke-RestMethod 'http://httpbin.org/basic-auth/PsUser/MyPassword' -cred $cred

编辑: 如 cmets 中所述,此方法不会在初始请求中发送 Authorization 标头。它等待质询响应,然后重新发送带有授权标头的请求。这不适用于在初始请求中需要凭据的服务。

【讨论】:

这与问题中的 sn-p 有何不同? 我确认它确实适用于基本身份验证,并提供了一个 URL 来测试它。我不希望用户来这个问题寻找如何使用基本身份验证并被告知-Credential 不起作用。在我提供的示例中显然是这样。你的情况一定是有什么东西导致它崩溃。 抱歉,我错过了您建议针对特定 URL 进行测试。就我而言, curl 有效,我提供 Authorization HTTP 标头的“手动”方法也有效,只是 Credential 参数无效。你不知道它在内部做什么吗?它只是添加相同的 HTTP 标头吗? @Borek 在运行 WireShark 时检查 httpbin.org 后,我发现使用 -Credential 不会在第一个请求中添加 Authorization 标头。 Httpbin.org 以 401 响应,然后 PowerShell 发送具有授权标头的第二个请求。 Httpbin.org 在第二次请求后以 200 响应。据我所知,您的方法是在第一个请求上发送标头的唯一方法。 我刚刚在weblog.west-wind.com/posts/2010/Feb/18/… 找到了这篇博客文章,其中讨论了与 HttpWebRequest 相同的问题,PowerShell 可能使用它来发送 HTTP 请求。【参考方案3】:

看来你应该在方法独立失败时组合它们。

创建凭据并将其添加到请求中。

创建标头并将其添加到请求中。

$username = "username";
$password = ConvertTo-SecureString –String "password" –AsPlainText -Force
$credential = New-Object –TypeName "System.Management.Automation.PSCredential" –ArgumentList $username, $password

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("0:1" -f $username,$password)))

$getProjectUri = "yourUri"
Invoke-RestMethod -Method Get -Uri $getProjectUri -Headers @Authorization = "Basic $base64AuthInfo"  -Credential $credential -ContentType "application/json"

【讨论】:

应该吗?我觉得这里缺少引用 不确定如何处理这个问题,我说应该,因为在某些情况下,某些实现似乎在第一次请求时需要两个凭据,就像 Borek 和 @Rynant 发现的那样。所以有时,根据被调用的服务器,您可能需要组合这些方法。 确认结合已解决的从 VSO 下载工件。谢谢。【参考方案4】:
#Requires -Version 6
$Uri = 'https://httpbin.org/basic-auth/user/pass'
# use "user" and "pass" when prompted for credentials
$Credential = Get-Credential
Invoke-RestMethod -Uri $Uri -Authentication Basic -Credential $Credential

【讨论】:

这里有很多非常古老的答案,但这是正确的现代答案。提供凭据对象并指定 -Authentication Basic 以在 PowerShell 中轻松进行基本身份验证。 但这似乎在 Windows Powershell 中不起作用? @NickG 显然,如 #Requires -Version 6 所述 抱歉 - 不知道我是怎么错过的! :)【参考方案5】:

此版本适用于Get-CredentialPSCredential 对象。它还可以在 PowerShell 6.0 中跨平台运行。它通过避免使用 BSTR 调用来做到这一点,在尝试从 PSCredential 提取密码时有时会建议使用 BSTR 调用。

$creds = Get-Credential
$unsecureCreds = $creds.GetNetworkCredential()
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("0:1" -f $unsecureCreds.UserName,$unsecureCreds.Password)))
Remove-Variable unsecureCreds

Invoke-RestMethod -Headers @Authorization=("Basic 0" -f $base64AuthInfo) ...

【讨论】:

【参考方案6】:

我发现使用-WebSession 参数有效,如果您预先创建一个带有凭据的WebRequestSession 对象。我不会重新讨论如何创建 PS Credential 对象,因为其他答案已经涵盖了这一点。

$WebSession = New-Object -TypeName Microsoft.PowerShell.Commands.WebRequestSession -Property @Credentials=$Credential
Invoke-RestMethod -Uri "your_URI" -WebSession $WebSession

这种方法在第一次调用时发送 auth 标头,因此避免了 401 响应。

顺便说一句,这种方法还可以用于设置代理详细信息(当使用参数指定时,它在所有版本的 PS 中都不能正常工作),并在您的 API 需要时处理 cookie。

【讨论】:

【参考方案7】:

您基本上需要将用户名和密码对作为编码凭据变量传递给Invoke-RestMethod

对我有用的是:

$USERNAME = 'user'
$PASSWORD = 'password'
$IDP_URL = 'example.com/token'


$credPair = "$($USERNAME):$($PASSWORD)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))

$parameters = @
    Uri         = $IDP_URL
    Headers     = @ 'Authorization' = "Basic $encodedCredentials" 
    Method      = 'POST'
    Body        = '...'
    ContentType = '...'


Invoke-RestMethod @parameters

请注意如何将请求参数提取到 $parameters 中,以避免命令臃肿。

【讨论】:

【参考方案8】:

我知道这是一个非常古老的问题,但我想在某处分享更新。我找到的使用 PowerShell 进行基本身份验证的帖子都没有为我工作。经过多次反复试验并通读 MS Docs,我发现我需要使用 -AllowUnencryptedAuthentication 参数,因为我使用 http 进行连接。我还必须升级我的 PS 版本才能访问该参数。

根据参数的描述:“允许通过未加密的连接发送凭据和机密。默认情况下,提供不以 https:// 开头的 Uri 的凭据或任何身份验证选项将导致错误和请求将中止以防止无意中通过未加密的连接以纯文本形式传递机密信息。若要覆盖此行为,请自担风险,请提供 AllowUnencryptedAuthentication 参数。"

【讨论】:

以上是关于PowerShell 的 Invoke-RestMethod 等效于 curl -u(基本身份验证)的主要内容,如果未能解决你的问题,请参考以下文章

powershell 测量PowerShell命令或PowerShell脚本的速度

powershell 如何定时执行 ps1

powershell远程下载exe并执行

windows powershell 怎么使用啊,是干啥用的

powershell报错?

Windows PowerShell ISE 是什么和 PowerShell 有什么区别