2

Elixir を使用して、REST API 経由で Azure ストレージ サービスにアクセスしようとしていますが、認証ヘッダーを機能させるのに苦労しています。ex_azureパッケージ ( erlazure のラッパー)を使用すると接続できますが、リクエストを作成してHTTPoisonを使用しようとすると接続できません。

最新のエラー メッセージ

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Error>
  <Code>AuthenticationFailed</Code>
  <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:00000000-0000-0000-0000-000000000000\nTime:2017-08-02T21:46:08.6488342Z</Message>
  <AuthenticationErrorDetail>The MAC signature found in the HTTP request '<signature>' is not the same as any computed signature. Server used following string to sign: 'GET\n\n\nWed, 02 Aug 2017 21:46:08
    GMT\nx-ms-date-h:Wed, 02 Aug 2017 21:46:08 GMT\nx-ms-version-h:2017-05-10\n/storage_name/container_name?comp=list'.</AuthenticationErrorDetail>
</Error>

最初の編集後

  <?xml version=\"1.0\" encoding=\"utf-8\"?>
  <Error>
    <Code>AuthenticationFailed</Code>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:00000000-0000-0000-0000-000000000000\nTime:2017-08-03T03:03:57.1385277Z</Message>
    <AuthenticationErrorDetail>The MAC signature found in the HTTP request '<signature>' is not the same as any computed signature. Server used following string to sign: 'GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Thu, 03 Aug
      2017 03:03:57 GMT\nx-ms-version:2017-04-17\n/storage_name/container_name\ncomp:list\nrestype:container'.</AuthenticationErrorDetail>
  </Error>

依存関係

# mix.exs
defp deps do
  {:httpoison, "~> 0.12"}
  {:timex, "~> 3.1"}
end

コード

  • 認証ヘッダー ( string_to_sign) を正しくフォーマットしていますか?
  • エンコード/デコードを正しく使用していますか?
  • HTTPoison にヘッダーを正しく追加していますか?
  • HTTPoison の代わりに REST アクションに別のものを使用する必要がありますか?
# account credentials
storage_name            = "storage_name"
container_name          = "container_name"
storage_key             = "storage_key"
storage_service_version = "2017-04-17" # fixed version

request_date =
  Timex.now
  |> Timex.format!("{RFC1123}") # Wed, 02 Aug 2017 00:52:10 +0000
  |> String.replace("+0000", "GMT") # Wed, 02 Aug 2017 00:52:10 GMT

# set canonicalized headers
x_ms_date    = "x-ms-date:#{request_date}"
x_ms_version = "x-ms-version:#{storage_service_version}"

# assign values for string_to_sign
verb                   = "GET\n"
content_encoding       = "\n"
content_language       = "\n"
content_length         = "\n"
content_md5            = "\n"
content_type           = "\n"
date                   = "\n"
if_modified_since      = "\n"
if_match               = "\n"
if_none_match          = "\n"
if_unmodified_since    = "\n"
range                  = "\n"
canonicalized_headers  = "#{x_ms_date}\n#{x_ms_version}\n"
canonicalized_resource = "/#{storage_name}/#{container_name}\ncomp:list\nrestype:container" # removed timeout. removed space

# concat string_to_sign
string_to_sign =
  verb                  <>
  content_encoding      <>
  content_language      <>
  content_length        <>
  content_md5           <>
  content_type          <>
  date                  <>
  if_modified_since     <>
  if_match              <>
  if_none_match         <>
  if_unmodified_since   <>
  range                 <>
  canonicalized_headers <>
  canonicalized_resource

# decode storage_key
{:ok, decoded_key} =
  storage_key
  |> Base.decode64

# sign and encode string_to_sign
signature =
  :crypto.hmac(:sha256, decoded_key, string_to_sign)
  |> Base.encode64

# build authorization header
authorization_header = "SharedKey #{storage_name}:#{signature}"

# build request and use HTTPoison
url     = "https://storage_name.blob.core.windows.net/container_name?restype=container&comp=list"
headers = [ # "Date": request_date,
           "x-ms-date": request_date, # fixed typo
           "x-ms-version": storage_service_version, # fixed typo
           # "Accept": "application/json",
           "Authorization": authorization_header]
options = [ssl: [{:versions, [:'tlsv1.2']}], recv_timeout: 500]

HTTPoison.get(url, headers, options)

ノート

私が使用した/試したいくつかのソース...

4

1 に答える 1