Serverless Frameworkで作成したAPI GatewayにIAMによるアクセス制御を行う

Serverless Frameworkで作成したAPI GatewayにIAMによるアクセス制御を行う

2017.11.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

API GatewayにはIAMでアクセスを制限する機能があります。

IAM アクセス権限により API へのアクセスを制御する

Serveress Frameworkで作成したAPIに、この機能によるアクセス制限を追加し、動作を確認するまでの手順について書いていきます。

手順について

LambdaとAPI Gatewayの構築

まずはServerless Frameworkでアクセス制限なしのLambdaとAPI Gatewayを作成します。Lambdaの言語はPython3系とします。

Serverless Frameworkをインストールします。今回は作業するローカルフォルダにインストールしました。

			
			
$ npm install serverless

		

バージョンを確認します。

			
			
$ ./node_modules/.bin/serverless --version
1.24.1

		

テンプレートを作成します。

			
			
$ ./node_modules/.bin/serverless create --template aws-python3

		

Lambdaのhandlerは自動生成されるものをそのまま使います。

			
			
import json


def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

    # Use this code if you don't use the http event with the LAMBDA-PROXY
    # integration
    """
    return {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "event": event
    }
    """


		

serverless.ymlを編集し、リージョンとAPI Gatewayの設定を行います。

			
			
provider:
  name: aws
  runtime: python3.6

# you can overwrite defaults here
#  stage: dev
  region: ap-northeast-1 # リージョン指定

(中略)

functions:
  hello:
    handler: handler.hello
    events: # ここから4行をAPI GatewayのGETメソッドを作成するために追加
      - http:
          path: hello
          method: get

		

デプロイを行います。

			
			
$ ./node_modules/.bin/serverless deploy

		

動作確認を行います。

			
			
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .
{
  "message": "Go Serverless v1.0! Your function executed successfully!",
  "input": {
    "resource": "/hello",
    "path": "/hello",
    "httpMethod": "GET",
    (以下略)
  }
}

		

ここではまだIAMによるアクセス制御は行なっていないため、curlでGETをできています。

IAMでのアクセス制御を追加

serverless.ymlのAPI Gatewayの設定に、IAMでのアクセス制御を追加します。

			
			
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
          authorizer: aws_iam # これを追加

		

デプロイを行います。

			
			
$ ./node_modules/.bin/serverless deploy

		

動作確認を行います。

			
			
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .
{
  "message": "Missing Authentication Token"
}

		

先ほどと異なり、今度はcurlでのGETをできません。

署名バージョン 4を使用してAPIにアクセスする

上記のAPIにアクセスするには署名バージョン 4による署名が必要となります。今回はRubyのaws-sigv4と言うgemを使って実行してみました。

gemのインストールを行います。

Gemfile

			
			
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem 'aws-sigv4'
gem 'aws-sdk', '~> 2'

		
			
			
$ bundle install --path vendor/bundle

		

APIにアクセスするプログラムは以下のようになります。

main.rb

			
			
require 'aws-sigv4'
require 'open-uri'
require 'aws-sdk'

ec2 = Aws::EC2::Client.new
credentials = ec2.config[:credentials].credentials

signer = Aws::Sigv4::Signer.new(
  service: 'execute-api',
  region: 'ap-northeast-1',
  access_key_id: credentials.access_key_id,
  secret_access_key: credentials.secret_access_key,
)

url = signer.presign_url(
  http_method: 'GET',
  url: 'https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello',
)

open(url){|io|
  puts io.read
}


		

以下のコマンドで実行します。

			
			
$ bundle exec ruby main.rb | jq .
{
  "message": "Go Serverless v1.0! Your function executed successfully!",
  "input": {
    "resource": "/hello",
    "path": "/hello",
    "httpMethod": "GET",
(以下略)

		

無事、APIにアクセスすることができました。

この記事をシェアする

FacebookHatena blogX

関連記事