簡體   English   中英

使用 OAuth 1.0 生成簽名時出現問題

[英]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 來測試您的授權,並比較生成的簽名。

https://www.postman.com/

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM