2014-02-24 3 views
1

사용자 지정 루비 코드 (azure 용 공식 PHP 라이브러리에서 이식 됨)를 사용하여 내 Windows 미디어 서비스 파일 용 SAS URL을 만들려고합니다. 코드는 다음과 같습니다Azure SAS URL에서 서명이 일치하지 않습니다.

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 
) 

이 나에게 다음 URL을 제공합니다 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)) 

이는 Github에서에 Azure SDK for Ruby의 소스 코드를 기반을

UPDATE

내가 발견 한 문제가 하나 더 있습니다. SAS URL을 발견하면 sig 쿼리 문자열 매개 변수의 끝에있는 %0A이 본질적으로 줄 바꿈 문자입니다. 확실하지 않음이오고있다하지만 난 당신이 다음 작업을 수행 할 때 자동으로 삽입됩니다 생각하는 이유 :

signature = Base64.encode64(signature) 

을하지만 내가 대신 encode64 방법을 strict_encode64를 사용하는 경우,이 삽입 모든 것이 잘 작동되지 않습니다. 다음 코드를 사용해보십시오.

signature = Base64.strict_encode64(signature) 

방금 ​​시도해 봤는데 잘되었습니다.

+0

유료 지원보다 유익한 정보를 제공해 주셔서 감사합니다 :) 어쨌든, "기본 Windows Media 서비스 액세스 키"를 wms_api_key 변수로 사용하고 있습니다. 내가 당신의 코드를 사용하려고 할 때'unpack : invalid 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