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

Returns the username for the request

Returns:

  • (String)


21
22
23
# File 'lib/tilia/http/auth/aws.rb', line 21

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



30
31
32
# File 'lib/tilia/http/auth/aws.rb', line 30

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



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/tilia/http/auth/aws.rb', line 43

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

  if auth_header[0] != 'AWS' || auth_header.size < 2
    @error_code = self.class::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



112
113
114
115
# File 'lib/tilia/http/auth/aws.rb', line 112

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



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/tilia/http/auth/aws.rb', line 66

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

  if content_md5
    # 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 = self.class::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 = self.class::ERR_INVALIDSIGNATURE
    return false
  end
  true
end