[英]Problem generating signature with OAuth 1.0
我在 powershell 中生成有效的 HMAC-SHA1 簽名時遇到問題,我最終想將其與 Flickr API 一起使用。 我已經堅持了幾個星期,所以如果有人請告訴我我做錯了什么,那將不勝感激。 謝謝:)
這是我寫的代碼:
$oauth_signature_method = 'HMAC-SHA1'
[string]$oauth_nonce = New-Guid
[int]$oauth_timestamp = [int](Get-Date -UFormat %s -Millisecond 0)
$oauth_version = '1.0'
$oauth_consumer_key = 'e1d618f39j69s6a87443b182a1e91084' #NOT REAL KEY
$oauth_consumer_secret = 'dd6jjff7423acb3a' # NOT REAL KEY
$url = 'https://www.flickr.com/services/oauth/request_token'
$method = 'GET'
$oauth_callback = 'oob'
$signature_key = [System.Uri]::EscapeDataString($oauth_consumer_key)+"&"+[System.Uri]::EscapeDataString($oauth_consumer_secret);
$method = $method.ToUpper()
$response=""
$oauth_signature = ""
# Build the signature
$SignatureBase = "$([System.Uri]::EscapeDataString($url))&"
$SignatureParams = @{
'oauth_callback' = [System.Web.HttpUtility]::UrlEncode($oauth_callback);
'oauth_consumer_key' = $oauth_consumer_key;
'oauth_nonce' = $oauth_nonce.replace("-","");
'oauth_signature_method' = $oauth_signature_method;
'oauth_timestamp' = $oauth_timestamp;
'oauth_version' = $oauth_version;
}
$SignatureParams.GetEnumerator() | Sort Name |foreach { $SignatureBase += [System.Uri]::EscapeDataString("$($_.Key)=$($_.Value)&") }
$SignatureBase = [System.Uri]::EscapeDataString("$method&")+$SignatureBase.TrimEnd('%26')
$SignatureBase = [System.Uri]::EscapeDataString($SignatureBase)
########################################################################################
# At this point:
# $SignatureBase = GET%2526https%253A%252F%252Fwww.flickr.com%252Fservices%252Foauth%252Frequest_token%26oauth_callback%253Doob%2526oauth_consumer_key%253De1d618f39j69s6a87443b182a1e91084%2526oauth_nonce%253D080a4203ff7e428bb898086dd
13a6697%2526oauth_signature_method%253DHMAC-SHA1%2526oauth_timestamp%253D1615550853%2526oauth_version%253D1.0
# $Signature_key = e1d618f39j69s6a87443b182a1e91084&dd6jjff7423acb3a
########################################################################################
$hmac = New-Object System.Security.Cryptography.HMACSHA1
$hmac.key = [System.Text.Encoding]::UTF8.GetBytes($Signature_key)
$oauth_signature = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($SignatureBase));
$oauth_signature = [System.Convert]::ToBase64String($oauth_signature)
########################################################################################
# At this point, $oauth_signature = tcKfNZmmRsGhnMmBaIuxRIINJfI=
########################################################################################
#Add the signature into the hashtable
$SignatureParams += @{'oauth_signature'=$oauth_Signature}
# Reconstruct the URL to include the new signature
$callurl = $url+"?"
$SignatureParams.GetEnumerator() | Sort Name | foreach { $callurl += "$($_.Key)=$($_.Value)&" }
$callurl = $callurl.TrimEnd('&')
########################################################################################
# At this point, this is the URL to get a token:
# https://www.flickr.com/services/oauth/request_token?oauth_callback=oob&oauth_consumer_key=e1d618f39j69s6a87443b182a1e91084&oauth_nonce=080a4203ff7e428bb898086dd13a6697&oauth_signature=tcKfNZmmRsGhnMmBaIuxRIINJfI=&o
auth_signature_method=HMAC-SHA1&oauth_timestamp=1615550853&oauth_version=1.0
########################################################################################
# Send the request to the oAuth server
try {$response = Invoke-RestMethod -uri $callurl -method $method -Headers $APIHeader}
當簽名發送到 Flickr 時,服務器會拒絕它,並聲明“oauth_problem=signature_invalid”。
我錯過了一步嗎?
謝謝。
查看Flickr 文檔中的示例有效負載:
GET&https%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Fwww.example.com%26oauth_consumer_key%3D653e7a6ecc1d528c516cc8f92cf98611%26oauth_nonce%3D95613465%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1305586162%26oauth_version%3D1.0
現在與腳本生成的有效負載字符串 ( $SignatureBase
) 進行比較:
GET%2526https%253A%252F%252Fwww.flickr.com%252Fservices%252Foauth%252Frequest_token%26oauth_callback%253Doob%2526oauth_consumer_key%253De1d618f39j69s6a87443b182a1e91084%2526oauth_nonce%253D0e014a368e2845f4860e27e87f6c5d01%2526oauth_signature_method%253DHMAC-SHA1%2526oauth_timestamp%253D1615561837%2526oauth_version%253D1.0
這告訴我們什么? 好吧,您似乎過度轉義了正在簽名的有效負載。
改變這個:
$SignatureParams.GetEnumerator() | Sort Name |foreach { $SignatureBase += [System.Uri]::EscapeDataString("$($_.Key)=$($_.Value)&") }
$SignatureBase = [System.Uri]::EscapeDataString("$method&")+$SignatureBase.TrimEnd('%26')
$SignatureBase = [System.Uri]::EscapeDataString($SignatureBase)
只是:
$SignatureParams.GetEnumerator() | Sort Name |foreach { $SignatureBase += [System.Uri]::EscapeDataString("$($_.Key)=$($_.Value)&") }
$SignatureBase = "$method&" + ($SignatureBase -replace '%26$')
現在剩下的就是通過更改此行來逃避生成的簽名:
$SignatureParams += @{'oauth_signature'=$oauth_Signature}
至:
$SignatureParams += @{ 'oauth_signature' = [uri]::EscapeDataString($oauth_Signature) }
我同意馬蒂亞斯的觀點。
您最初在簽名庫中轉義 url,然后在將所有元素連接到簽名庫之前轉義所有元素。
然后在這里,您轉義了整個構造的字符串:
$SignatureBase = [System.Uri]::EscapeDataString($SignatureBase)
這是用百分比轉義碼 (%25) 替換每個先前轉義字符的百分比符號。
省略上面提到的代碼行。 正如文檔所述,每個元素都應該在與 & 符號連接之前進行轉義。
https://oauth.net/core/1.0a/#anchor13
另外,我會將 $signatureParams 哈希表轉換為字符串數組,然后-join '&'
。 這消除了稍后去除尾隨編碼的“&”的需要。
我不相信您需要對 sigKey 進行 UTF8 編碼。 你的::EscapeDataString()
方法應該處理這個問題。
請注意,在 base64 對 $ouath_signature 進行編碼后,必須先對其進行轉義(URL 編碼),然后再將其分配給 AuthZ header 中的 'oauth_signature' 參數。
我建議使用 Postman 來測試您的授權,並比較生成的簽名。
They have an OAuth 1.0 document on how to use Postman: https://learning.postman.com/docs/sending-requests/authorization/#oauth-10
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.