You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ruby调用Azure Data Lake Storage Gen2 REST API认证失败求助

Fixing "Server failed to authenticate the request" for ADLS Gen2 Ruby REST API Calls

Let’s walk through what’s going wrong in your code and fix that authentication error step by step—Azure’s SharedKey signature is picky about exact formatting, so a tiny mistake here will break everything.

The Main Issues in Your Current Code

  • Incomplete signature string: The final critical part (resource: filesystem) isn’t actually being added to your stringToSign—it’s a standalone line, so your signature is missing a required component.
  • Missing x-ms-date header: Azure needs this header (in UTC) to validate the signature’s validity period, and you have to include it in the string you sign. Your current code doesn’t send this header at all.
  • Hardcoded values in signature logic: Your encode_string method uses fake storage account and filesystem names instead of your actual ones—so the signature doesn’t match the request you’re sending.
  • Wrong signature generation step: After calculating the HMAC-SHA256, you’re running an extra SHA256 digest on it before Base64 encoding. Azure expects the raw HMAC result encoded directly.
  • Broken URI parameters: You’re using HTML-encoded & instead of plain &, and the directory='/' syntax isn’t correct for this filesystem list operation.

Corrected Ruby Code

require 'rubygems'
require 'net/http'
require 'uri'
require 'openssl'
require 'base64'
require 'time'

# Replace these with your actual credentials
access_key = "YOUR_STORAGE_ACCOUNT_ACCESS_KEY"
storage_account_name = 'r1dltest'
target_filesystem = 'datalake'

# Fix URI: use plain &, correct parameter structure for listing filesystem
uri_string = "https://#{storage_account_name}.dfs.core.windows.net/#{target_filesystem}?resource=filesystem&maxresults=5000&recursive=false"
uri = URI.parse(uri_string)

# Get current UTC time (required for x-ms-date header)
current_utc_time = Time.now.utc.iso8601

# Set up the GET request
request = Net::HTTP::Get.new(uri)

# Add mandatory headers
request["x-ms-date"] = current_utc_time
request["x-ms-version"] = "2018-11-09"

# Generate valid SharedKey signature
signature = generate_shared_key(access_key, storage_account_name, target_filesystem, request)
request["Authorization"] = "SharedKey #{storage_account_name}:#{signature}"

# Execute the request
req_options = { use_ssl: uri.scheme == "https" }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

# Print results for debugging
puts "Response Status: #{response.code} #{response.message}"
puts response.body

def generate_shared_key(access_key, storage_account_name, filesystem_name, request)
  # Build the string to sign exactly as Azure requires
  string_to_sign = [
    request.method, # HTTP method (GET here)
    request["Content-Encoding"] || "",
    request["Content-Language"] || "",
    request["Content-Length"] || "",
    request["Content-MD5"] || "",
    request["Content-Type"] || "",
    "", # Leave Date blank since we're using x-ms-date
    request["If-Modified-Since"] || "",
    request["If-Match"] || "",
    request["If-None-Match"] || "",
    request["If-Unmodified-Since"] || "",
    request["Range"] || "",
    # x-ms headers, sorted by name (only x-ms-date and x-ms-version here)
    "x-ms-date:#{request['x-ms-date']}",
    "x-ms-version:#{request['x-ms-version']}",
    # Resource path: /storage-account/filesystem
    "/#{storage_account_name}/#{filesystem_name}",
    # The query parameter that defines the operation
    "resource:filesystem"
  ].join("\n")

  # Decode the base64 access key
  decoded_access_key = Base64.decode64(access_key)
  # Compute HMAC-SHA256 hash
  hmac_hash = OpenSSL::HMAC.digest('sha256', decoded_access_key, string_to_sign)
  # Encode the hash to base64 for the signature
  Base64.strict_encode64(hmac_hash)
end

What We Fixed (And Why)

  1. Added x-ms-date header: Azure uses this UTC timestamp to ensure the signature isn’t reused after a certain time. We include it in both the request and the string to sign.
  2. Completed the signature string: We properly appended all required parts, including the resource:filesystem component that was missing before.
  3. Removed hardcoded values: The signature now uses your actual storage account and filesystem names, so it matches the request context.
  4. Fixed signature generation: We got rid of the extra SHA256 step—Azure wants the raw HMAC result encoded directly to base64.
  5. Cleaned up the URI: Replaced HTML-encoded characters and adjusted parameters to match ADLS Gen2’s REST API specs for listing filesystem contents.

Quick Tips to Avoid Future Issues

  • Always use UTC time for x-ms-date—local time will instantly fail authentication.
  • Double-check your access key: make sure there are no extra spaces or missing characters when you copy it from Azure Portal.
  • Verify permissions: your access key should belong to an account with Storage Blob Data Contributor or equivalent rights on the ADLS Gen2 filesystem.

内容的提问来源于stack exchange,提问作者aadame

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:04:13