Class: Azure::Signature

Inherits:
Object
  • Object
show all
Defined in:
lib/azure/signature.rb

Overview

The Signature class encapsulates an canonicalized resource string.

Constant Summary collapse

VERSION =

The version of the azure-signature library.

'0.2.2'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource, key) ⇒ Signature

Creates and returns an Azure::Signature object taking a resource (URL) as an argument and a storage account key. The resource will typically be an Azure storage account endpoint.

Note that the resource is automatically escaped.



40
41
42
43
44
45
46
# File 'lib/azure/signature.rb', line 40

def initialize(resource, key)
  @resource = Addressable::URI.escape(resource)
  @uri = Addressable::URI.parse(@resource)
  @account_name = @uri.host.split(".").first.split("-").first
  @key = Base64.strict_decode64(key)
  @canonical_resource = canonicalize_resource(@uri)
end

Instance Attribute Details

#account_nameObject (readonly)

The name of the storage account, based on the resource.



24
25
26
# File 'lib/azure/signature.rb', line 24

def 
  @account_name
end

#canonical_headersObject (readonly)

Returns the value of attribute canonical_headers.



32
33
34
# File 'lib/azure/signature.rb', line 32

def canonical_headers
  @canonical_headers
end

#canonical_resourceObject (readonly) Also known as: canonical_url

The canonical version of the resource.



18
19
20
# File 'lib/azure/signature.rb', line 18

def canonical_resource
  @canonical_resource
end

#keyObject (readonly)

The base64-decoded account key passed to the constructor.



21
22
23
# File 'lib/azure/signature.rb', line 21

def key
  @key
end

#resourceObject (readonly) Also known as: url

The resource (URL) passed to the constructor.



15
16
17
# File 'lib/azure/signature.rb', line 15

def resource
  @resource
end

#uriObject (readonly)

A URI object that encapsulates the resource.



27
28
29
# File 'lib/azure/signature.rb', line 27

def uri
  @uri
end

Instance Method Details

#blob_signature(headers = {}) ⇒ Object Also known as: file_signature, queue_signature

Generate a signature for use with the blob service. Use the headers hash to pass optional information. The following additional keys are supported:

  • :auth_type. Either ‘SharedKey’ (the default) or ‘SharedKeyLight’.

  • :verb. The http verb used for SharedKey auth. The default is ‘GET’.

  • :x_ms_date. The x-ms-date used. The default is Time.now.httpdate.

  • :x_ms_version. The x-ms-version used. The default is ‘2015-02-21’.

  • :auth_string. If true, prepends the auth_type + account name to the

    result and returns a string. The default is false.
    

You may also use the string forms as keys, e.g. “Auth-Type” instead of :auth_type, if you prefer.

The other headers of potential significance are below. Note that you are not required to set any of them.

  • ‘Content-Encoding’

  • ‘Content-Language’

  • ‘Content-Length’

  • ‘Content-MD5’

  • ‘Content-Type’

  • ‘Date’

  • ‘If-Modified-Since’

  • ‘If-Match’

  • ‘If-None-Match’

  • ‘If-Unmodified-Since’

  • ‘Range’

The result is a digest string that you can use as an authorization header for future http requests to (presumably) Azure storage endpoints.

Example:

require 'azure-signature'
require 'rest-client'

url = "https://yourstuff.blob.core.windows.net/system?restype=container&comp=list&include=snapshots"
key = "xyzabcwhatever"

sig  = Signature.new(url, key)
date = Time.now.httpdate
vers = '2015-02-21'

headers = {
  'x-ms-date'    => date,
  'x-ms-version' => vers,
  'Accept'       => 'application/xml',
  :auth_string   => true,
}

sig = sig.blob_signature(headers)
headers['Authorization'] = sig

req = RestClient::Request.new(
  :method => 'get',
  :url => url,
  :headers => headers
)

response = req.execute
p response.body


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/azure/signature.rb', line 155

def blob_signature(headers = {})
  headers.clone.each{ |k,v| headers[k.to_s.downcase.tr('_', '-')] = v }

  auth_string = headers.delete('auth-string') || false
  auth_type   = headers.delete('auth_type') || 'SharedKey'
  verb        = headers.delete('verb') || 'GET'

  unless ['SharedKey', 'SharedKeyLight'].include?(auth_type)
    raise ArgumentError, "auth type must be SharedKey or SharedKeyLight"
  end

  headers['x-ms-date'] ||= Time.now.httpdate
  headers['x-ms-version'] ||= '2015-02-21'

  if auth_type == 'SharedKeyLight'
    headers['date'] ||= headers['x-ms-date'] || Time.now.httpdate
  end

  body = generate_string(verb, headers, auth_type).encode('UTF-8')

  if auth_string
    "SharedKey #{}:" + sign(body)
  else
    sign(body)
  end
end

#signature(type, args = {}) ⇒ Object

Generic wrapper method for getting a signature, where type can be :table, :blob, :queue, or :file.



188
189
190
191
192
193
194
195
196
197
# File 'lib/azure/signature.rb', line 188

def signature(type, args = {})
  case type.to_s.downcase
    when 'table'
      table_signature(args)
    when 'blob', 'file', 'queue'
      blob_signature(args)
    else
      raise ArgumentError, "invalid signature type '#{type}'"
  end
end

#table_signature(options = {}) ⇒ Object

Generate a signature for use with the table service. Use the options hash to pass optional information. The following keys are supported:

  • :auth_type. Either ‘SharedKey’ (the default) or ‘SharedKeyLight’.

  • :verb. The http verb used for SharedKey auth. The default is ‘GET’.

  • :date. The date (or x-ms-date) used. The default is Time.now.httpdate.

  • :content_md5. The Content-MD5 if desired. The default is nil.

  • :content_type. The Content-Type if desired. The default is nil.

  • :auth_string. If true, prepends the auth_type + account name to the

    result and returns a string. The default is false.
    

You may also use the string forms as keys, e.g. “Auth-Type” instead of :auth_type, if you prefer.

The result is a digest string that you can use as an authorization header for future http requests to (presumably) Azure storage endpoints.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/azure/signature.rb', line 65

def table_signature(options = {})
  options.clone.each{ |k,v| options[k.to_s.downcase.tr('_', '-')] = v }

  auth_type    = options['auth-type'] || 'SharedKey'
  verb         = options['verb'] || 'GET'
  date         = options['date'] || Time.now.httpdate
  auth_string  = options['auth-string'] || false
  content_md5  = options['content-md5']
  content_type = options['content-type']

  unless ['SharedKey', 'SharedKeyLight'].include?(auth_type)
    raise ArgumentError, "auth type must be SharedKey or SharedKeyLight"
  end

  if auth_type == 'SharedKey'
    body = [verb, content_md5, content_type, date, canonical_resource].join("\n").encode('UTF-8')
  else
    body = [date, canonical_resource].join("\n").encode('UTF-8')
  end

  if auth_string
    "#{auth_type} #{}:" + sign(body)
  else
    sign(body)
  end
end