Skip to content

Commit 28685e8

Browse files
committed
Extend AwsService:getAuthorizationHeader() / AwsV4Signature:getAuthorizationHeader() so that the caller can pass the arbitrary host name for signer to calculate the hash with.
1 parent 77984d5 commit 28685e8

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

src/lua/api-gateway/aws/AwsService.lua

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,12 @@ function _M:getHttpClient()
187187
end
188188

189189
function _M:getAWSHost()
190-
return self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
190+
-- FIXME: the endpoint cannot always be determined mechanically; http://docs.aws.amazon.com/general/latest/gr/rande.html
191+
if self.aws_service == "s3" then
192+
return self.aws_service .. "-" .. self.aws_region .. ".amazonaws.com"
193+
else
194+
return self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
195+
end
191196
end
192197

193198
function _M:getCredentials()
@@ -201,16 +206,18 @@ function _M:getCredentials()
201206
return return_obj
202207
end
203208

204-
function _M:getAuthorizationHeader(http_method, path, uri_args, body)
209+
function _M:getAuthorizationHeader(http_method, path, uri_args, body, host_override)
205210
local credentials = self:getCredentials()
211+
credentials.aws_endpoint = self:getAWSHost()
206212
credentials.aws_region = self.aws_region
207213
credentials.aws_service = self.aws_service
208214
local awsAuth = AWSV4S:new(credentials)
209-
local authorization = awsAuth:getAuthorizationHeader(http_method,
215+
local authorization, payload_hash = awsAuth:getAuthorizationHeader(http_method,
210216
path, -- "/"
211217
uri_args, -- ngx.req.get_uri_args()
212-
body)
213-
return authorization, awsAuth, credentials.token
218+
body,
219+
host_override)
220+
return authorization, awsAuth, credentials.token, payload_hash
214221
end
215222

216223
---
@@ -278,7 +285,7 @@ function _M:performAction(actionName, arguments, path, http_method, useSSL, time
278285
end
279286

280287

281-
local authorization, awsAuth, authToken = self:getAuthorizationHeader(request_method, request_path, uri_args, request_body)
288+
local authorization, awsAuth, authToken, payloadHash = self:getAuthorizationHeader(request_method, request_path, uri_args, request_body)
282289

283290
local t = self.aws_service_name .. "." .. actionName
284291
local request_headers = {
@@ -287,7 +294,8 @@ function _M:performAction(actionName, arguments, path, http_method, useSSL, time
287294
["Accept"] = "application/json",
288295
["Content-Type"] = content_type,
289296
["X-Amz-Target"] = t,
290-
["x-amz-security-token"] = authToken
297+
["x-amz-security-token"] = authToken,
298+
["x-amz-content-sha256"] = payloadHash
291299
}
292300
if ( extra_headers ~= nil ) then
293301
for headerName, headerValue in pairs(extra_headers) do
@@ -329,4 +337,4 @@ function _M:performAction(actionName, arguments, path, http_method, useSSL, time
329337
return ok, code, headers, status, body
330338
end
331339

332-
return _M
340+
return _M

src/lua/api-gateway/aws/AwsV4Signature.lua

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ function HmacAuthV4Handler:new(o)
1717
setmetatable(o, self)
1818
self.__index = self
1919
if ( o ~= nil) then
20+
self.aws_endpoint = o.aws_endpoint
2021
self.aws_service = o.aws_service
2122
self.aws_region = o.aws_region
2223
self.aws_secret_key = o.aws_secret_key
2324
self.aws_access_key = o.aws_access_key
25+
self.token = o.token
2426
end
2527
-- set amazon formatted dates
2628
local utc = ngx.utctime()
@@ -52,7 +54,8 @@ local function get_hashed_canonical_request(method, uri, querystring, headers, r
5254
-- add canonicalHeaders
5355
local canonicalHeaders = ""
5456
local signedHeaders = ""
55-
for h_n,h_v in pairs(headers) do
57+
for _, p in ipairs(headers) do
58+
local h_n, h_v = p[1], p[2]
5659
-- todo: trim and lowercase
5760
canonicalHeaders = canonicalHeaders .. h_n .. ":" .. h_v .. "\n"
5861
signedHeaders = signedHeaders .. h_n .. ";"
@@ -63,13 +66,14 @@ local function get_hashed_canonical_request(method, uri, querystring, headers, r
6366
hash = hash .. canonicalHeaders .. "\n"
6467
.. signedHeaders .. "\n"
6568

66-
hash = hash .. _hash(requestPayload or "")
69+
requestPayloadHash = _hash(requestPayload or "")
70+
hash = hash .. requestPayloadHash
6771

6872
ngx.log(ngx.DEBUG, "Canonical String to Sign is:\n" .. hash)
6973

7074
local final_hash = _hash(hash)
7175
ngx.log(ngx.DEBUG, "Canonical String HASHED is:\n" .. final_hash .. "\n")
72-
return final_hash
76+
return final_hash, signedHeaders, requestPayloadHash
7377
end
7478

7579
local function get_string_to_sign(algorithm, request_date, credential_scope, hashed_canonical_request)
@@ -141,36 +145,44 @@ function HmacAuthV4Handler:formatQueryString(uri_args)
141145
return uri
142146
end
143147

144-
function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table, request_payload )
148+
function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table, request_payload, host_override)
145149
local uri_args = self:formatQueryString(uri_arg_table)
146150
local utc = ngx.utctime()
147151
local date1 = self.aws_date_short
148152
local date2 = self.aws_date
153+
local host = self.aws_endpoint
154+
if host_override ~= nil then
155+
host = host_override
156+
end
149157

150158
local headers = {}
151-
headers.host = self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
152-
headers["x-amz-date"] = date2
159+
table.insert(headers, {"host", host})
160+
table.insert(headers, {"x-amz-date", date2})
161+
if self.token ~= nil then
162+
table.insert(headers, {"x-amz-security-token", self.token})
163+
end
153164

154165
-- ensure parameters in query string are in order
166+
local hashed_canonical_request, signed_headers, request_payload_hash = get_hashed_canonical_request(
167+
http_method, request_uri,
168+
uri_args,
169+
headers, request_payload)
155170
local sign = _sign( get_derived_signing_key( self.aws_secret_key,
156171
date1,
157172
self.aws_region,
158173
self.aws_service),
159174
get_string_to_sign("AWS4-HMAC-SHA256",
160175
date2,
161176
date1 .. "/" .. self.aws_region .. "/" .. self.aws_service .. "/aws4_request",
162-
get_hashed_canonical_request(
163-
http_method, request_uri,
164-
uri_args,
165-
headers, request_payload) ) )
166-
return sign
177+
hashed_canonical_request) )
178+
return sign, signed_headers, request_payload_hash
167179
end
168180

169-
function HmacAuthV4Handler:getAuthorizationHeader(http_method, request_uri, uri_arg_table, request_payload )
170-
local auth_signature = self:getSignature(http_method, request_uri, uri_arg_table, request_payload)
181+
function HmacAuthV4Handler:getAuthorizationHeader(http_method, request_uri, uri_arg_table, request_payload, host_override)
182+
local auth_signature, signed_headers, request_payload_hash = self:getSignature(http_method, request_uri, uri_arg_table, request_payload, host_override)
171183
local authHeader = "AWS4-HMAC-SHA256 Credential=" .. self.aws_access_key.."/" .. self.aws_date_short .. "/" .. self.aws_region
172-
.."/" .. self.aws_service.."/aws4_request,SignedHeaders=host;x-amz-date,Signature="..auth_signature
173-
return authHeader
184+
.."/" .. self.aws_service.."/aws4_request,SignedHeaders="..signed_headers..",Signature="..auth_signature
185+
return authHeader, request_payload_hash
174186
end
175187

176188
return HmacAuthV4Handler

0 commit comments

Comments
 (0)