はじめに
岡崎です。今回はAPIGatewayのオーソライザについて書きたいと思います。
オーソライザーとは??
一言で言うと、認可サーバです。
- 各Function毎で、想定しているIPと違うから弾きたい
- ヘッダが想定しているものがついてきてるよね
- JsonWebTokenが正しく検証できるんだっけ?? …etc
上記みたいなことをやりたい時に使います。オーソライザーを使用することで、上記の部分を各Functionで書かずに済みます。(共通処理として持たせることが可能) オーソライザーは、任意のFunctionと紐づけることが可能です。 つまり、認証用LambdaFunctionを作成しておけば、後は設定することでオーソライザーとして使用することが可能になります。
流れ
クライアント(APIGatewayで作成したエンドポイントを指定) => オーソライザー(認証処理) => 各LambdaFunctionでの処理
ソース部分
(ここでは、例外処理とかその他もろもろの部分を省略して書きます。)
def lambda_handler(event, context):
if DEVELOP:
if not is_expected_source_ip(source_ip=event['requestContext']['identity']['sourceIp']):
return generate_policy('user', 'Deny', event['methodArn'])
header = get_header(event)
if is_header_empty(header=header):
return generate_policy('user', 'Deny', event['methodArn'])
if is_header_none(header=header):
return generate_policy('user', 'Deny', event['methodArn'])
if not is_expected_ua(ua=header['user_agent']):
return generate_policy('user', 'Deny', event['methodArn'])
if not is_collect_token(token=event['headers']['token'].encode('utf-8')):
return generate_policy('user', 'Deny', event['methodArn'])
return generate_policy('user', 'Allow', event['methodArn'])
def generate_policy(principal_id='user', effect=None, resource=None):
auth_response = {}
auth_response['principalId'] = principal_id
auth_response['context'] = \
{
'stringKey': 'stringval',
'numberKey': '123',
'booleanKey': 'true'
}
if effect is not None and resource is not None:
policy_document = {}
policy_document['Version'] = '2012-10-17'
policy_document['Statement'] = []
statement_one = {}
statement_one['Action'] = 'execute-api:Invoke'
statement_one['Effect'] = effect
statement_one['Resource'] = resource
policy_document['Statement'] = statement_one
auth_response['policyDocument'] = policy_document
return auth_response
こんな感じで、書くことができます。 ただし、普通のFunctionとは違い、 レスポンスは固定の物を返さないといけません。(AWSの仕様となります。)
ここが固定の物ではない場合は、補足部分にあるような謎なレスポンスをクライアントに返すこととなります。 この固定のレスポンス部分は、generate_policy() で定義している内容になります。 Allowの時は、後続のLambdaの処理に行き、Denyの時は、クライアント側に403(認証エラー)のステータスコードを返すことになります。
補足
- 固定レスポンス以外をレスポンスしてしまった時
{ "message": null }
- 403の場合のレスポンス
{
"Message": "User is not authorized to access this resource with an explicit deny"
}
岡崎拓哉
2016年に入社した新卒。ドラムとインコが好きな人。
最近は、デザイン駆動設計や関数型プログラミングに興味あり。
マネジメントも覚えていきたい系エンジニア。