API Gateway の Lambda Authorizer をRuby で実装してみる
概要
API Gateway の機能である Lambda Authorizer を Ruby で実装してみました。
オーソライザーの中身は AWS Cognito を利用したトークンベースで行っています。
デプロイには Serverless を使用しました。
コードはこちらでも公開しています。
Lambda Authorizer とは
Lambda 関数を使用してAPIへのアクセスを制御する API Gateway の機能です。
API Gateway Lambda オーソライザーの使用
Authorizer 関数の実装
ここでは Cognito ユーザープールのトークンを使ってクライアントを認可しています。
リクエストヘッダーに含まれるベアラートークンを検証し、成功すればIAMポリシーを返してAPIへのアクセスを許可します。
require 'jwt'
require 'open-uri'
ISS = "https://cognito-idp.#{ENV['COGNITO_USER_POOL_ID'].gsub(/(?<=\d)(.*)/, '')}.amazonaws.com/#{ENV['COGNITO_USER_POOL_ID']}"
def authorize(event:, context:)
puts 'Auth function invoked'
token = event['authorizationToken'][7..-1]
header = Base64.urlsafe_decode64(token.split('.')[0])
kid = JSON.parse(header, symbolize_names: true)[:kid]
res = OpenURI.open_uri("#{ISS}/.well-known/jwks.json")
keys = JSON.parse(res.read, symbolize_names: true)[:keys]
key = keys.find { |k| k[:kid] == kid }
pem = JWT::JWK.import(key).public_key
begin
decoded = JWT.decode token, pem, true, verify_iat: true, iss: ISS, verify_iss: true, algorithm: 'RS256'
rescue JWT::JWKError => e
puts "Provided JWKs is invalid: #{e}"
return generate_policy(nil, 'Deny', event['methodArn'])
rescue JWT::DecodeError => e
puts "Failed to authorize: #{e}"
return generate_policy(nil, 'Deny', event['methodArn'])
end
generate_policy(decoded[0]['sub'], 'Allow', event['methodArn'])
end
def generate_policy(principal_id, effect, resource)
auth_response = { principalId: principal_id }
auth_response[:policyDocument] = {
Version: '2012-10-17',
Statement: [
{ Action: 'execute-api:Invoke', Effect: effect, Resource: resource }
]
}
auth_response
end
認可後に実行される Lambda 関数の実装
def private_endpoint(event:, context:)
{ statusCode: 200, body: 'Only logged in users can see this' }
end
デプロイする
APIの構築に必要なAWSのリソースを定義したファイルを作成します。
8行目のCOGNITO_USER_POOL_ID
の値を実際のユーザープールIDに置き換える必要があります。
privateEndpoint
のevents
にあるauthorizer
でこの関数が実行される前に呼び出される Lambda Authorizer の設定を行なっています。
Serverlessフレームワークを使えば簡単にこうした設定をすることができます。
service: aws-ruby-cognito-custom-authorizers
provider:
name: aws
runtime: ruby2.5
environment:
COGNITO_USER_POOL_ID: COGNITO_USER_POOL_ID
plugins:
- serverless-hooks-plugin
custom:
hooks:
package:initialize:
- bundle install --deployment
functions:
auth:
handler: auth.authorize
privateEndpoint:
handler: handler.private_endpoint
events:
- http:
path: api/private
method: get
authorizer: auth
cors:
origins:
- '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
Gemfileを作成し、必要なライブラリをインストールします。
bundle init
echo \"jwt\" >> Gemfile
bundle
デプロイするには以下のコマンドを実行します。
npm install -g serverless
npm install --save serverless-hooks-plugin
sls deploy
APIのテスト
curlコマンドを使ってAPIのテストをすることができます。
<id_token>
には Cognito ユーザーのIDトークンをコピーしてください。
APIのURLはデプロイ後にコンソールに表示されるURLに置き換えます。
curl --header "Authorization: bearer <id_token>" https://{api}.execute-api.{region}.amazonaws.com/api/privat
おわり
AWS上に作成したリソースは以下のコマンドで削除できます。
sls remove
Author And Source
この問題について(API Gateway の Lambda Authorizer をRuby で実装してみる), 我々は、より多くの情報をここで見つけました https://qiita.com/nightswinger/items/9bab4abfc416364f4c7f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .