ruby - 尝试使用 Ruby 对我的数据湖存储 gen2 进行 Azure REST API 调用时,“服务器无法对请求进行身份验证”
问题描述
我希望能够通过 ruby 脚本访问我的 Azure Data Lake Storage Gen2 帐户,以便我可以添加文件/目录。
嗅探 adls gen2 存储 api 调用
使用rest api从powershell连接到azure data Lake Storage gen2
我尝试按照上述指南尝试在 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
我的代码的输出。
解决方案
我对红宝石不熟悉。但是,就我现在而言,每个要签名的字符串之间都有一个换行符。在官方文档中,您应该使用代表新行的 '\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-目录
推荐阅读
- java - 在服务中使用 ViewModel
- android - 如何使用 Android 上导航栏上方的空间?
- swift - 如何按可能为 nil 的键进行分组并获取具有非可选键类型的字典?
- python - 比较不同列中的两条数据时,Pandas if 语句连接字符串错误
- android - 按字符串值对 ArrayList 排序为双精度
- perl - 如何从 perl 中的 fstat 获取本地 mtime?
- powershell - Is it possible to register powershell scheduled job from another scheduled job?
- python-3.x - Query Oracle database from Cloud Foundry using Python
- r - Pivot_longer 6 列到 3 列
- c++ - 尝试在 C++ 中将节点添加到链接列表的末尾时出现分段错误(核心转储)错误