Skip to content

Commit

Permalink
added doubleUrlEncode parameter to AWS V4 signature (#11)
Browse files Browse the repository at this point in the history
* added doubleUrlEncode parameter to AWS V4 signature as per AWS requirements (useful to fix LambdaService)
  • Loading branch information
ddragosd committed Jun 7, 2016
1 parent 77984d5 commit e44349e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 11 deletions.
4 changes: 3 additions & 1 deletion src/lua/api-gateway/aws/AwsService.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ end
-- o.security_credentials_host - optional. the AWS URL to read security credentials from and figure out the iam_user
-- o.security_credentials_port - optional. the port used when connecting to security_credentials_host
-- o.shared_cache_dict - optional. AWSIAMCredentials uses it to store IAM Credentials.
-- o.doubleUrlEncode - optional. Whether to double url-encode the resource path
-- when constructing the canonical request for AWSV4 signature.
--
-- NOTE: class inheirtance inspired from: http://www.lua.org/pil/16.2.html
function _M:new(o)
Expand Down Expand Up @@ -205,7 +207,7 @@ function _M:getAuthorizationHeader(http_method, path, uri_args, body)
local credentials = self:getCredentials()
credentials.aws_region = self.aws_region
credentials.aws_service = self.aws_service
local awsAuth = AWSV4S:new(credentials)
local awsAuth = AWSV4S:new(credentials, self.doubleUrlEncode)
local authorization = awsAuth:getAuthorizationHeader(http_method,
path, -- "/"
uri_args, -- ngx.req.get_uri_args()
Expand Down
20 changes: 17 additions & 3 deletions src/lua/api-gateway/aws/AwsV4Signature.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ function HmacAuthV4Handler:new(o)
self.aws_region = o.aws_region
self.aws_secret_key = o.aws_secret_key
self.aws_access_key = o.aws_access_key
---
-- Whether to double url-encode the resource path when constructing the
-- canonical request. By default, double url-encoding is true.
-- Different sigv4 services seem to be inconsistent on this. So for
-- services that want to suppress this, they should set it to false.
self.doubleUrlEncode = o.doubleUrlEncode or true
end
-- set amazon formatted dates
local utc = ngx.utctime()
Expand Down Expand Up @@ -93,10 +99,14 @@ local function urlEncode(inputString)
inputString = string.gsub (inputString, "([^%w %-%_%.%~])",
function (c) return string.format ("%%%02X", string.byte(c)) end)
inputString = ngx.re.gsub (inputString, " ", "+", "ijo")
-- AWS workarounds
-- AWS workarounds following Java SDK
-- see https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L80-87
-- replace '+' ( %2B ) with ( %20 )
inputString = ngx.re.gsub(inputString, "%2B", "%20", "ijo")

-- replace %2F with "/"
inputString = ngx.re.gsub(inputString, "%2F", "/", "ijo")
-- replace %7E with "~"
inputString = ngx.re.gsub(inputString, "%7E", "~", "ijo")
end
return inputString
--[[local s = ngx.escape_uri(inputString)
Expand Down Expand Up @@ -151,6 +161,10 @@ function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table,
headers.host = self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
headers["x-amz-date"] = date2

local encoded_request_uri = request_uri
if (self.doubleUrlEncode == true) then
encoded_request_uri = urlEncode(request_uri)
end
-- ensure parameters in query string are in order
local sign = _sign( get_derived_signing_key( self.aws_secret_key,
date1,
Expand All @@ -160,7 +174,7 @@ function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table,
date2,
date1 .. "/" .. self.aws_region .. "/" .. self.aws_service .. "/aws4_request",
get_hashed_canonical_request(
http_method, request_uri,
http_method, encoded_request_uri,
uri_args,
headers, request_payload) ) )
return sign
Expand Down
14 changes: 9 additions & 5 deletions test/integration/kms.t
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use lib 'lib';
use strict;
use warnings;
use Test::Nginx::Socket::Lua;
use Cwd qw(cwd);

Expand Down Expand Up @@ -143,14 +145,18 @@ __DATA__
}
location = /latest/meta-data/iam/security-credentials/test-iam-user {
set_by_lua $expiration '
local offset = os.time() - os.time(os.date("!*t"))
return os.date("%Y-%m-%dT%H:%M:%SZ", os.time() + math.abs(offset) + 20)
';
return 200 '{
"Code" : "Success",
"LastUpdated" : "2014-11-03T01:56:20Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "$TEST_NGINX_AWS_CLIENT_ID",
"SecretAccessKey" : "$TEST_NGINX_AWS_SECRET",
"Token" : "$TEST_NGINX_AWS_SECURITY_TOKEN",
"Expiration" : "2014-11-03T08:07:52Z"
"Expiration" : "$expiration"
}';
}
location /test-with-iam {
Expand Down Expand Up @@ -179,9 +185,6 @@ __DATA__
local KeyId = list.Aliases[1].AliasName
ngx.say("KEY-ALIAS:" .. tostring(KeyId))
local KeyId = "alias/GW-CACHE-MK"
ngx.say("KEY ALIAS:" .. tostring(KeyId))
-- generate a data key
local cipher = service:generateDataKey(KeyId, "AES_256")
local blob = cipher.CiphertextBlob
Expand All @@ -202,12 +205,13 @@ __DATA__
end
';
}
--- timeout: 60
--- more_headers
X-Test: test
--- request
GET /test-with-iam
--- response_body_like eval
[".*KEY\\sALIAS\\:.*BLOB\\:.*"]
[".*KEY-ALIAS\\:.*BLOB\\:.*"]
--- error_code: 200
--- no_error_log
[error]
Expand Down
14 changes: 12 additions & 2 deletions test/integration/lambda.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

# vim:set ft= ts=4 sw=4 et fdm=marker:
use lib 'lib';
use strict;
use warnings;
use Test::Nginx::Socket::Lua;
use Cwd qw(cwd);

Expand Down Expand Up @@ -130,8 +132,16 @@ __DATA__
key1 = "value-1",
key2 = "value-2"
}
local invokeResult, code, headers, status, body = service:invoke(functionName, payload)
ngx.say("EXECUTION RESULT:" .. tostring(body))
local context = {}
context.identity = {}
context.identity.accountId = tostring(ngx.var.oauth_token_user_id)
local context_json = cjson.encode(context)
local invokeResult, code, headers, status, body = service:invoke(functionName, payload,context_json)
if (code == 200) then
ngx.say("EXECUTION RESULT:" .. tostring(body))
else
ngx.say(tostring(body))
end
-- TODO: delete the hello-world function
Expand Down

0 comments on commit e44349e

Please sign in to comment.