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。
我正在尝试编写一个 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。