首页 > 解决方案 > 尝试使用 Ruby 对我的数据湖存储 gen2 进行 Azure REST API 调用时,“服务器无法对请求进行身份验证”

问题描述

我希望能够通过 ruby​​ 脚本访问我的 Azure Data Lake Storage Gen2 帐户,以便我可以添加文件/目录。

嗅探 adls gen2 存储 api 调用

http://sql.pawlikowski.pro/2019/03/09/how-to-sniff-adls-gen2-storage-rest-api-calls-to-azure-using-azure-storage-explorer/

使用rest api从powershell连接到azure data Lake Storage gen2

http://sql.pawlikowski.pro/2019/03/10/connecting-to-azure-data-lake-storage-gen2-from-powershell-using-rest-api-a-step-by-step-guide/

我尝试按照上述指南尝试在 ruby​​ 代码中复制 powershell 脚本。我还尝试了存储帐户访问密钥中的两个密钥,但仍然出现相同的错误。

require 'rubygems'
require 'rest_client'
require 'json'

require 'net/http'
require 'uri'
require 'securerandom'
require 'openssl'
require 'base64'
require 'digest' 

access_key = "ACCESS KEY HERE"
shared_key = encode_string(access_key)

storage_account_name = 'r1dltest'
target_filesystem = 'datalake'

uri_string = "https://#{storage_account_name}.dfs.core.windows.net/#{target_filesystem}?directory='/'&maxresults=5000&recursive=false&resource=filesystem"

## Parse URI
puts("> Parsing URI: #{uri_string}")
uri = URI.parse(uri_string)

## PUT request.
puts("> Setting up PUT request.")
request = Net::HTTP::Get.new(uri)

## Set headers.
puts("> Setting authorization headers")
puts ("Auth Header Key: #{storage_account_name}:#{shared_key}")
request["Authorization"] = "SharedKey #{storage_account_name}:#{shared_key}" 
request["x-ms-version"] = "2018-11-09"

## Options
req_options = {
    use_ssl: uri.scheme == "https",
}

## Execute request.
puts("> Executing request...")
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
    http.request(request)
end

puts(response.body)
def encode_string(key)
    n = ""
    method = "GET"
    date = ""
    version = "2018-11-09"
    storage_account_name = "saname"
    file_system_name = "fsname"

    stringToSign = method + n
    stringToSign += n # Content-Encoding
    stringToSign += n # Content-Language
    stringToSign += n # Content-Length
    stringToSign += n # Content-MD5
    stringToSign += n # Content-Type
    stringToSign += n # Date
    stringToSign += n # If-Modified-Since
    stringToSign += n # If-Match
    stringToSign += n # If-None-Match
    stringToSign += n # If-Unmodified-Since
    stringToSign += n # Range

    stringToSign += "x-ms-date:" + n +
                    "x-ms-version: #{version}" + n
    stringToSign += "/#{storage_account_name}/#{file_system_name}" + n +
                    "recursive: true" + n
                    "resource: filesystem" + n
    puts(stringToSign)

    shared_key = Base64.decode64(key)    
    hashedKey = OpenSSL::HMAC.digest('sha256', shared_key, stringToSign)    
    signedString = Base64.strict_encode64(Digest::SHA256.digest(hashedKey))

    return signedString
end

我的代码的输出。

在此处输入图像描述

标签: rubyazurepowershell

解决方案


我对红宝石不熟悉。但是,就我现在而言,每个要签名的字符串之间都有一个换行符。在官方文档中,您应该使用代表新行的 '\n'。但是,您只使用了一个空字符串。

而且,您还忘记设置 x-ms-date 标头值。

stringToSign += "x-ms-date:" + n +
                "x-ms-version: #{version}" + n

顺便说一句,微软官方建议开发者使用 Azure AD 进行身份验证:https ://docs.microsoft.com/en-us/azure/data-lake-store/data-lakes-store-authentication-using-azure-active-目录


推荐阅读