Class: Tilia::Http::Auth::Aws

Inherits:
AbstractAuth show all
Defined in:
lib/tilia/http/auth/aws.rb

Overview

HTTP AWS Authentication handler

Use this class to leverage amazon’s AWS authentication header

Constant Summary collapse

ERR_NOAWSHEADER =
1
ERR_MD5CHECKSUMWRONG =
2
ERR_INVALIDDATEFORMAT =
3
ERR_REQUESTTIMESKEWED =
4
ERR_INVALIDSIGNATURE =
5

Instance Attribute Summary collapse

Attributes inherited from AbstractAuth

#realm

Instance Method Summary collapse

Instance Attribute Details

#access_keyString (readonly)

Returns the username for the request

Returns:

  • (String)


46
47
48
# File 'lib/tilia/http/auth/aws.rb', line 46

def access_key
  @access_key
end

#error_codeObject

An error code, if any

This value will be filled with one of the ERR_* constants

Returns:

  • int



16
17
18
# File 'lib/tilia/http/auth/aws.rb', line 16

def error_code
  @error_code
end

Instance Method Details

#initObject

Gathers all information from the headers

This method needs to be called prior to anything else.

Returns:

  • bool



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/tilia/http/auth/aws.rb', line 29

def init
  auth_header = @request.header('Authorization') || ''
  auth_header = auth_header.split(' ')

  if auth_header[0] != 'AWS' || auth_header.size < 2
    @error_code = ERR_NOAWSHEADER
    return false
  end

  (@access_key, @signature) = auth_header[1].split(':')

  true
end

#require_loginvoid

This method returns an undefined value.

Returns an HTTP 401 header, forcing login

This should be called when username and password are incorrect, or not supplied at all



98
99
100
101
# File 'lib/tilia/http/auth/aws.rb', line 98

def 
  @response.add_header('WWW-Authenticate', 'AWS')
  @response.status = 401
end

#validate(secret_key) ⇒ Object

Validates the signature based on the secretKey

Parameters:

  • secret_key (String)

Returns:

  • bool



52
53
54
55
56
57
58
59
60
61
62
63
64
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
91
# File 'lib/tilia/http/auth/aws.rb', line 52

def validate(secret_key)
  content_md5 = @request.header('Content-MD5')

  if content_md5.present?
    # We need to validate the integrity of the request
    body = @request.body
    @request.body = body

    if content_md5 != Base64.strict_encode64(::Digest::MD5.digest(body.to_s))
      # content-md5 header did not match md5 signature of body
      @error_code = ERR_MD5CHECKSUMWRONG
      return false
    end
  end

  request_date = @request.header('x-amz-date')
  request_date = @request.header('Date') unless request_date

  return false unless validate_rfc2616_date(request_date)

  amz_headers = self.amz_headers

  signature = Base64.strict_encode64(
    hmacsha1(
      secret_key,
      @request.method + "\n" +
      content_md5 + "\n" +
      @request.header('Content-type').to_s + "\n" +
      request_date + "\n" +
      amz_headers +
      @request.url
    )
  )

  unless @signature == signature
    @error_code = ERR_INVALIDSIGNATURE
    return false
  end
  true
end