Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend AwsService:getAuthorizationHeader() / AwsV4Signature:getAuthorizationHeader() #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

moriyoshi
Copy link

  • In order to allow the caller to pass the arbitrary host name for signer to calculate the hash with.
  • In order to enable the caller to obtain the payload sha256 hash which is used to calculate the signature and must be passed to the endpoint along with the other signed headers.

These changes are essential to use S3 API.

…izationHeader() so that the caller can pass the arbitrary host name for signer to calculate the hash with.
@moriyoshi moriyoshi force-pushed the payjp/extend-get-authz-header branch from 247e2d2 to 28685e8 Compare May 30, 2016 17:07
@@ -187,7 +187,12 @@ function _M:getHttpClient()
end

function _M:getAWSHost()
return self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
-- FIXME: the endpoint cannot always be determined mechanically; http://docs.aws.amazon.com/general/latest/gr/rande.html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe an S3Service.lua implementation ( similar to LambdaService.lua ) may "override" in lua-style this method:

S3Service.lua:

local AwsService = require "api-gateway.aws.AwsService"
local cjson = require "cjson"
local error = error

local _M = AwsService:new({ ___super = true })
local super = {
    instance = _M,
    constructor = _M.constructor
}

function _M.new(self, o)
    ngx.log(ngx.DEBUG, "S3Service() o=", tostring(o))
    local o = o or {}
    o.aws_service = "s3"
    -- aws_service_name is used in the X-Amz-Target Header: i.e Kinesis_20131202.ListStreams
    o.aws_service_name = "S3"

    super.constructor(_M, o)

    setmetatable(o, self)
    self.__index = self
    return o
end

function _M:getAWSHost()
    return return self.aws_service .. "-" .. self.aws_region  .. ".amazonaws.com"
end

Note _M:getAWSHost() method. WDYT ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed a quick access to S3 service with authentication at that moment and I didn't know what these are supposed to be like, so I decided not to create a "subclass" for it. Overriding the function perfectly makes sense to me. That said, I'd bet the part of the code which determines the correct endpoint for a given service would be easier to maintain if it was centralized in one place.

@felixbuenemann
Copy link

I am currently using the following patch with 1.7.0 to allow generating signatures for s3 AWS4 using proxy_pass in openresty:

diff --git a/src/lua/api-gateway/aws/AwsV4Signature.lua b/src/lua/api-gateway/aws/AwsV4Signature.lua
index 3936937..8f9af85 100644
--- a/src/lua/api-gateway/aws/AwsV4Signature.lua
+++ b/src/lua/api-gateway/aws/AwsV4Signature.lua
@@ -28,6 +28,8 @@ function HmacAuthV4Handler:new(o)
         -- services that want to suppress this, they should set it to false.
         self.doubleUrlEncode = o.doubleUrlEncode or true
     end
+    local divider = self.aws_service == "s3" and "-" or "."
+    self.aws_endpoint = self.aws_service .. divider .. self.aws_region .. ".amazonaws.com"
     -- set amazon formatted dates
     local utc = ngx.utctime()
     self.aws_date_short = string.gsub(string.sub(utc, 1, 10),"-","")
@@ -153,12 +155,11 @@ end

 function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table, request_payload )
     local uri_args = self:formatQueryString(uri_arg_table)
-    local utc = ngx.utctime()
     local date1 = self.aws_date_short
     local date2 = self.aws_date

     local headers = {}
-    headers.host = self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
+    headers.host = self.aws_endpoint
     headers["x-amz-date"] = date2

     local encoded_request_uri = request_uri

As noted by @jlapier the distinction of s3-region.amazonaws.com vs. s3.region.amazonaws.com doesn't really seem to be needed and could be fixed in my case by using the dot seperator when defining the endpoint mapping in the nginx config.

For local testing though I really need to be able to pass in the endpoint, so I can use this with minio.

I'm not really familiar with lua, so not sure if my changes are the right way to do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants