Skip to content

Instantly share code, notes, and snippets.

@babajidemm
Created November 11, 2019 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save babajidemm/1ceb3e9d3470dbdced87749f4de81030 to your computer and use it in GitHub Desktop.
Save babajidemm/1ceb3e9d3470dbdced87749f4de81030 to your computer and use it in GitHub Desktop.
A Lambda function for AWS API Gateway Authentication using Ruby runtime (v2.5)
require "base64"
def lambda_handler(event:, context:)
#puts "event: #{event.inspect}"
#puts "context: #{context.inspect}"
authorization_token = event['authorizationToken']
return deny(event, "Auth Token unavailable") unless authorization_token
authorization_token_partials = authorization_token.split(' ')
if authorization_token_partials.length > 1
#if sent as "Basic xxxxxxxx"
authorization_token = decode(authorization_token_partials[1])
end
auth_partials = authorization_token.split(':')
return deny(event, "Auth Token invalid: #{authorization_token}") unless auth_partials.length > 1
auth_username = auth_partials[0]
auth_password = auth_partials[1]
return deny(event, "Auth Token invalid: #{authorization_token}") unless "valid_username".eql?(auth_username) && "valid_password".eql?(auth_password)
accept(event, auth_username)
end
def deny(event, error_msg)
compute_result(event, {"access_effect": "Deny", "arn": event['methodArn'], "auth": event['authorizationToken'], "error_msg": error_msg})
end
def accept(event, principal_id)
compute_result(event, {"access_effect": "Allow", "arn": event['methodArn'], "auth": event['authorizationToken'], "principal_id": principal_id})
end
def decode(auth_token)
Base64.decode64(auth_token)
end
def compute_result(event, options)
puts "Result: #{options[:access_effect]}"
method_arn = options[:arn]
arn_partials = method_arn.split(':')
aws_context_name = arn_partials[0]
aws_context = arn_partials[1]
aws_api_name = arn_partials[2]
aws_region = arn_partials[3]
aws_account_id = arn_partials[4]
api_gateway_arn_partials = arn_partials[5].split('/')
rest_api_id = api_gateway_arn_partials[0]
stage = api_gateway_arn_partials[1]
http_method = api_gateway_arn_partials[2]
proxy_path = api_gateway_arn_partials[3]
api_arn = "#{aws_context_name}:#{aws_context}:#{aws_api_name}:#{aws_region}:#{aws_account_id}:#{rest_api_id}/#{stage}/*/*"
# needs to return JSON in a certain format
{
"principalId": "#{options[:principal_id]}",
"policyDocument": {
"Version": '2012-10-17',
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "#{options[:access_effect]}",
"Resource": "#{api_arn}"
}
]
},
"context": {
"error_msg": "#{options[:error_msg]}"
}
}
end
@babajidemm
Copy link
Author

Notice here that we are validating the credentials against “valid_username“ and “valid_password“ after decoding the sent token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment