2014-02-24 107 views
1

我正嘗試使用自定義Ruby代碼(從官方php庫中移植到Azure)爲我的Windows媒體服務文件創建SAS網址。該代碼看起來像這樣:簽名與Azure SAS不匹配網址

def create_signature(path = '/', resource = 'b', permissions = 'r', start = '', expiry = '', identifier = '') 
    # If resource is a container, remove the last part (which is the filename) 
    path = path.split('/').reverse.drop(1).reverse.join('/') if resource == 'c' 
    canonicalizedResource = "/mediasvc78m7lfh2gnn2x/#{path}" 

    stringToSign = [] 
    stringToSign << permissions 
    stringToSign << start 
    stringToSign << expiry 
    stringToSign << canonicalizedResource 
    stringToSign << identifier 

    stringToSign = stringToSign.join("\n") 
    signature = OpenSSL::HMAC.digest('sha256', wms_api_key, stringToSign.encode(Encoding::UTF_8)) 
    signature = Base64.encode64(signature) 

    return signature 
end 

def createSignedQueryString(path = '/', query_string = '', resource = 'b', permissions = 'r', start = '', expiry = '', identifier = '') 
    base = 'https://mediasvc78m7lfh2gnn2x.blob.core.windows.net' 
    uri = Addressable::URI.new 

    # Parts 
    parts  = {} 
    parts[:st] = URI.unescape(start) unless start == '' 
    parts[:se] = URI.unescape(expiry) 
    parts[:sr] = URI.unescape(resource) 
    parts[:sp] = URI.unescape(permissions) 
    parts[:si] = URI.unescape(identifier) unless identifier == '' 
    parts[:sig] = URI.unescape(create_signature(path, resource, permissions, start, expiry)) 

    uri.query_values = parts 
    return "#{base}/#{path}?#{uri.query}" 
end 

當運行:

puts createSignedQueryString(
    'asset-12514a3b-565f-4150-9543-e3c2b4531428/video.mp4', 
    nil, 
    'b', 
    'r', 
    (Time.now - 5*60).utc.iso8601, 
    (Time.now + 30*60).utc.iso8601 
) 

它給了我以下網址:https://mediasvc78m7lfh2gnn2x.blob.core.windows.net/asset-12514a3b-565f-4150-9543-e3c2b4531428/video.mp4?se=2014-02-20T12%3A59%3A19Z&sig=RDc9nVMuf1dy%2BPrnzCkA8pZfgry2ZwrF08u9itf4v%2FA%3D%0A&sp=r&sr=b&st=2014-02-20T12%3A24%3A19Z

當我嘗試我的瀏覽器指向它,我得到:

<Error> 
<Code>AuthenticationFailed</Code> 
<Message> 
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:ee7fd18f-cd1f-4179-8a58-c8b746d0549c Time:2014-02-20T12:29:27.0468171Z 
</Message> 
<AuthenticationErrorDetail> 
Signature did not match. String to sign used was r 2014-02-20T12:24:19Z 2014-02-20T12:59:19Z /mediasvc78m7lfh2gnn2x/asset-12514a3b-565f-4150-9543-e3c2b4531428/video.mp4 
</AuthenticationErrorDetail> 
</Error> 

你有什麼想法什麼可以導致該錯誤(或如何調試呢?),以及如何應對 接着就,隨即?提前致謝。

回答

2

假設您直接從門戶使用存儲密鑰,並在您的wms_api_key變量中使用存儲密鑰(或換句話說,您的wms_api_key是Base64編碼的字符串,我相信您需要首先將其轉換爲字節數組進行計算。簽名你需要做的是這樣的:。

signature = OpenSSL::HMAC.digest('sha256', Base64.strict_decode64(wms_api_key), stringToSign.encode(Encoding::UTF_8)) 

這是基於Azure SDK for Ruby在Github上的源代碼

UPDATE

我發現了另外一個問題。如果您注意到您的SAS網址,您會在sig末尾註意到%0A查詢字符串參數,它基本上是一個新的行字符。不知道爲什麼,這是未來,但我覺得當你做以下則自動插入:如果我使用strict_encode64代替encode64方法

signature = Base64.encode64(signature) 

然而,這不是插入,一切的偉大工程。因此請嘗試以下代碼:

signature = Base64.strict_encode64(signature) 

我剛試過,它對我很好。

+0

謝謝你付出更多的幫助比支付天藍色的支持:)無論如何,我使用「主要Windows媒體服務訪問密鑰」作爲我的wms_api_key變量。當我試圖使用它的代碼時,它會拋出'unpack:無效的base64(ArgumentError)' – mbajur

+0

我明白了。實際上,您需要將存儲帳戶密鑰用於wms_api_key變量,而不是媒體服務訪問密鑰。 –

+0

哦,好的。我沒有任何信息應該用在那裏,所以我用wms鍵試過。無論如何,它仍然會拋出同樣的錯誤。新鏈接是https://mediasvc78m7lfh2gnn2x.blob.core.windows.net/asset-12514a3b-565f-4150-9543-e3c2b4531428/video.mp4?se=2014-02-25T09%3A21%3A28Z&sig=AV9nieaGkq1x3EXEvk3T2CQz0ZK41g9rwgxrTOjnnVs%3D%0A&sp = r&sr = b&st = 2014-02-25T08%3A46%3A28Z – mbajur