OneLogin REST API与PowerShell的Invoke-RestMethod

时间:2016-09-04 17:35:15

标签: rest powershell onelogin

我正在使用OneLogin REST API,并且似乎无法使用PUT方法进行任何调用。当我在Postman中测试时,我可以传递一个原始的JSON体,如下所示:

{
   "role_id_array":  [
                        115028
                     ]
}

到端点:

https://api.us.onelogin.com/api/1/users/ / add_roles

这很好用。但是,当我尝试使用PowerShell的Invoke-RestMethod命令执行相同操作时,我收到400 Bad Request错误。我的代码如下所示:

$Splat = @{
    Method      = $Method
    Uri         = https://api.us.onelogin.com/api/1/users/12345678/add_roles
    ContentType = "application/json"
    Headers     = @{authorization = "bearer:$($Token.access_token)"}
    Body        = @{role_id_array = @(123456)}
}

Invoke-RestMethod @Splat

到目前为止,我对任何GET调用都没有任何问题,只有PUT。另外,如果我运行我通过ConvertTo-Json传入的Body哈希表,输出看起来就像上面的工作示例。有没有人想过为什么这不起作用?

2 个答案:

答案 0 :(得分:8)

我能够让PUT工作!

如何从Invoke-RestMethod

获取丰富的错误响应数据

首先,我使用this blog post here,它有一个很好的方法来检索Invoke-RestMethodWebRequest cmdlet的完整错误消息。

在他的方法中,首先定义一个名为Failure的函数。

function Failure {
$global:helpme = $body
$global:helpmoref = $moref
$global:result = $_.Exception.Response.GetResponseStream()
$global:reader = New-Object System.IO.StreamReader($global:result)
$global:responseBody = $global:reader.ReadToEnd();
Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
break
}

然后,在这样的try Catch块中包装所有的Invoke-RestMethod调用。

try { 
  $e = Invoke-WebRequest 'https://api.us.onelogin.com/api/1/users/$id' `
     -Headers  @{ Authorization = "bearer:$token" } `
     -Body  ( @{ phone = "7709746046" } | ConvertTo-Json ) `
     -Method Put -ErrorAction:Stop -ContentType 'application/json' 
     } 
catch {Failure}

现在当您遇到错误时,您可以看到实际的消息,例如

> Status: A system exception was caught.
{"status":{"error":true,"code":400,"type":"bad request","message":{"description":"notes is not a valid attribute for user model","attribute":"notes"}}}
The request body has been saved to $global:helpme

这对帮助我摆脱遇到的错误非常有帮助,并且我能够使用PUT动词更新用户条目并使其正常工作。

解决您的问题

我只需对代码进行两处更改即可使其正常工作。

首先,在URI周围加上引号,因为您的示例代码没有它们,并且您必须在哈希表中围绕字符串使用引号。

最后,将您的角色ID数组传输到ConvertTo-JSON,否则数据将作为字符串发送,就像您在fiddler中找到的那样。

通过这两项更改,请参阅我的请求和回复

$Splat = @{
    Method      = 'PUT'
    Uri         = 'https://api.us.onelogin.com/api/1/users/27697924/add_roles'
    ContentType = "application/json"
    Headers     = @{authorization = "bearer:$token" }
    Body        = @{role_id_array = @(143175)} | ConvertTo-Json
}

try {Invoke-RestMethod @Splat -ErrorAction Stop }
catch {Failure}

以下是回复:

status                                                 
------                                                 
@{type=success; message=Success; error=False; code=200}

更新:我们做到了,现在已经修复了!

如果您认为PowerShell应该显示非200状态代码的实际服务器响应,那么请帮助关注Github上的这个open issue on the PowerShell项目页面。

添加您的反馈或竖起大拇指,我们可能会在将来的语言版本中对其进行更改。

此问题现已修复,自PowerShell v6.1起

答案 1 :(得分:0)

好的,所以我崩溃并安装了Fiddler,我想我已经做了些什么。 PowerShell cmdlet似乎不知道如何处理application / json contenttype的数组。我不确定XML会是这种情况,因为我还没有测试过。

我改变了主体以使用直接的json字符串,它起作用了:

$Body = "{ `"role_id_array`": [123456] }"

如果我使用一个哈希表,其值设置为这样的数组:

$Body = @{role_id_array = 115028,128732}

然后我会得到400故障响应。 Fiddler告诉我发生了什么 - 这是原始请求:

PUT https://api.us.onelogin.com/api/1/users/12345678/add_roles HTTP / 1.1 授权:持票人:3c93ae2-redacted- User-Agent:Mozilla / 5.0(Windows NT; Windows NT 6.3; en-US)WindowsPowerShell / 5.1.14394.1000 Content-Type:application / json 主持人:api.us.onelogin.com 内容长度:33 的 role_id_array = System.Object的%5B%5D

请注意,数组未正确转换,而是将Invoke-RestMethod简单地折叠为typename定义,类似于Export-Csv处理数组属性值的方式。

所以我觉得我在使用PUT方法时遇到了问题,因为我的所有GET调用都在工作,但那是一个红色的鲱鱼。真正的问题是处理REST端点,该端点需要数组值的请求参数值。

编辑:我发现有人在2014年发布了此问题,但他的解决方法是将-ContentType参数设置为' application / json':

Powershell v4 Invoke-RestMethod body sends System.Object

我已经完成了这个并且仍然遇到了同样的问题。这是一个错误吗?