Powershell OAuth 1.0 'one-legged' 使用 HMAC-SHA1 的身份验证失败

Powershell OAuth 1.0 'one-legged' authentication with HMAC-SHA1 fails

我正在尝试编写一个 Powershell 脚本,以便我可以从使用 'one-legged' 的网络 API 获取数据(这意味着您只有消费者密钥(用户名)和消费者机密(密码) ) OAuth1.0认证。我研究了 OAuth1.0 文档 (https://oauth.net/core/1.0/),然后生成了以下脚本:

$response                   = $null
$url                        = 'https://api.holidaypictures.com/api/v1.0/0'

$oauth_consumer_key         = 'myusername@domain.com'
$oauth_consumer_secret      = 'SuperSecretHash'
$oauth_nonce                = -join ((65..90) + (97..122) | Get-Random -Count 12 | % {[char]$_})
$oauth_signature_method     = 'HMAC-SHA1'
$oauth_timestamp            = [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds
$oauth_token                = '' # Don't have this because 'one-legged' authentication
$oauth_token_secret         = '' # Don't have this because 'one-legged' authentication
$oauth_version              = '1.0'

$method                     = 'POST'

$base_string  = 'oauth_consumer_key=' + $oauth_consumer_key
$base_string += '&oauth_nonce=' + $oauth_nonce
$base_string += '&oauth_signature_method=' + $oauth_signature_method
$base_string += '&oauth_timestamp=' + $oauth_timestamp
$base_string += '&oauth_token=' + $oauth_token
$base_string += '&oauth_version=' + $oauth_version

$signature_base_string      = $method + '&' + [System.Web.HttpUtility]::UrlEncode($url) + '&' + [System.Web.HttpUtility]::UrlEncode($base_string)

$key = $oauth_consumer_secret + '&' + $oauth_token_secret
$hmacsha1 = new-object System.Security.Cryptography.HMACSHA1;
$hmacsha1.Key = [System.Text.Encoding]::ASCII.GetBytes($key);
$oauth_signature = [System.Convert]::ToBase64String($hmacsha1.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($signature_base_string)));
$oauth_signature
$oauth_signature = [System.Web.HttpUtility]::UrlEncode($oauth_signature)

$oauth_signature

$auth  = 'OAuth '
$auth += 'oauth_consumer_key="' + $oauth_consumer_key + '",'
$auth += 'oauth_nonce="' + $oauth_nonce + '",'
$auth += 'oauth_signature="' + $oauth_signature + '",'
$auth += 'oauth_signature_method="' + $oauth_signature_method + '",'
$auth += 'oauth_timestamp="' + $oauth_timestamp + '",'
$auth += 'oauth_token="' + $oauth_token + '",'
$auth += 'oauth_version="' + $oauth_version + '"'

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("Authorization", $auth)
$body = "{`n    `"pageSize`": 10,`n `"sort`": [`n       {`n         `"key`": `"info.date`",`n           `"direction`": -1`n         `n      }`n ],`n    `"idSelection`": [],`n  `"query`": []`n}"

$response = Invoke-RestMethod -Method $method -Headers $headers -body $body -Uri $url

当我运行此代码时出现以下错误:

Invoke-RestMethod : {"status":401,"message":"Could not authorize request","scope":"SECURITY","details":null}
At line:47 char:13
+ $response = Invoke-RestMethod -Method $method -Headers $headers -body ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (Method: POST, Reque\u2026application/json
}:HttpRequestMessage) [Invoke-RestMethod], HttpResponseException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

换句话说:认证失败。有谁可以帮我解决这个问题吗?不胜感激!

顺便说一下MoreApp.com API...不知道有没有帮助。

我认为问题是 [System.Web.HttpUtility]::UrlEncode 没有按照 OAuth 的要求编码为 RFC3986。一方面,它没有将百分比编码大写。根据 RFC3986,“URI 生产者和规范化者应该对所有百分比编码使用大写十六进制数字。”我不确定它是否转义了 RFC3986 要求的所有相同字符。

There is a function "ConvertTo-PSUrlEncodedString" in the PSAuth module that does RFC3986 encoding. 我窃取了该函数并将其带入您的脚本,将所有 [System.Web.HttpUtility]::UrlEncode 替换为 ConvertTo-PSUrlEncodedString 函数。然后它起作用了。但使用 PSAuth 可能会更好,因为它会做一些额外的事情,例如对参数进行排序、添加端口号等,以确保一切都符合 OAuth。