Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ユースケースで学ぶ!API Gateway + Lambda Authorizer 実践入門(...

ユースケースで学ぶ!API Gateway + Lambda Authorizer 実践入門(CDK)

Shiraishi

July 26, 2022
Tweet

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ  w"84ࣄۀຊ෦ίϯαϧς Οϯά෦ w"84ΤϯδχΞ ϑϩϯτ ΤϯυΤϯδχΞ w8FCडୗ4&4$. w"84 )5.-

    $44  +BWB4DSJQU 5ZQF4DSJQU  1)1 1FSM $ 1ZUIPO നੴ੒ҰʢShiraishi Seiichiʣ
  2. "1*(BUFXBZ࣮૷  import { IdentitySource, LambdaIntegration, RequestAuthorizer, RestApi } from

    ‘aws-cdk-lib/aws-apigateway'; const api = new RestApi(this, 'zendesk-webhook-api', { deployOptions: { stageName: ‘v1’ // default Ͱ͸ prod ͕ੜ੒͞ΕΔ } }) const auth = new RequestAuthorizer(this, 'zendeskWebhookAuthorizer', { handler: authorizerFunction, // LambdaAuthorizer ࣮૷ identitySources: [ IdentitySource.header(‘Authorization'), IdentitySource.header(‘X-Request-Id’) ] })
  3. "1*(BUFXBZ࣮૷  const webhookApi = api.root.addResource('resource'); webhookApi.addMethod( 'POST', new LambdaIntegration(postResourceFunction),

    { authorizer: auth } ) webhookApi.addCorsPreflight({ statusCode: 200, allowOrigins: Cors.ALL_ORIGINS, allowMethods: Cors.ALL_METHODS, allowHeaders: Cors.DEFAULT_HEADERS, })
  4. -BNCEB"VUIPSJ[FS࣮૷  import { ManagedPolicy, Effect, PolicyStatement, Role, ServicePrincipal }

    from ‘aws-cdk-lib/aws-iam'; // policy ͷ࣮૷ const authorizerFunctionPolicy = new ManagedPolicy(this, "authorizer-function-policy", { managedPolicyName: "authorizer-function-policy", statements: [ new PolicyStatement({ effect: Effect.ALLOW, actions: [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", ], resources: ["arn:aws:logs:*:*:*"], }), ] }); const authorizerFunctionRole = new Role(this, "authorizer-function-role", { roleName: "authorizer-function-role", assumedBy: new ServicePrincipal("lambda.amazonaws.com"), managedPolicies: [authorizerFunctionPolicy] });
  5. -BNCEB"VUIPSJ[FS࣮૷  // policy ͷ࣮૷ const authorizerInvokePolicy = new ManagedPolicy(this,

    "authorizer-invoke-policy", { managedPolicyName: "authorizer-invoke-policy", statements: [ new PolicyStatement({ effect: Effect.ALLOW, actions: [ "sts:AssumeRole", ], resources: ['*'], }) ] }) const authorizerInvokeRole = new Role(this, 'authorizer-invoke-role', { roleName: "authorizer-invoke-role", assumedBy: new ServicePrincipal('apigateway.amazonaws.com'), managedPolicies: [authorizerInvokePolicy] });
  6. -BNCEB"VUIPSJ[FS࣮૷  const authorizerFunction = new Function(this, ‘authorizer-function', { functionName:

    'authorizer-function', description: ‘Zendesk WebhookͷBasicೝূΛݕূ͢Δ', code: new AssetCode(“resources"), // ೚ҙͷύεΛઃఆ handler: “auth/authorizer.handler", // ೚ҙͷύεΛઃఆ runtime: Runtime.PYTHON_3_9, role: authorizerFunctionRole, environment: { // parameter store Λར༻ SSM_ZENDESK_USERNAME: "/zendesk/username", SSM_ZENDESK_PASSWORD: "/zendesk/password", } }); // API Gateway ͕ Lambda Λ࣮ߦ͢ΔͨΊͷݖݶ authorizerFunction.grantInvoke(authorizerInvokeRole);
  7. -BNCEB"VUIPSJ[FS࣮૷  import base64 import json import logging import os

    from hooks.utils import common TOKYO = "ap-northeast-1" logger = logging.getLogger() logger.setLevel(logging.INFO) zendesk_username = os.environ['SSM_ZENDESK_USERNAME'] zendesk_password = os.environ['SSM_ZENDESK_PASSWORD'] def handler(event, context): try: basic_header = event[“headers"]["Authorization"] req_id = event["headers"]["X-Request-Id"] result = is_valid(basic_header, common.get_parameter_value(zendesk_username), common.get_parameter_value(zendesk_password)) if result is True: return gen_policy(req_id, "Allow") return gen_policy(req_id, "Deny") except Exception as e: logger.error(e) raise Exception("Unauthorized") authorizer.py
  8. -BNCEB"VUIPSJ[FS࣮૷  def is_valid(basic_header, username, password): basic_username_and_pasword = base64.b64encode( f"{username}:{password}".encode("utf-8")

    ) sig = f"Basic {basic_username_and_pasword.decode('utf-8')}" if basic_header == sig: return True return False def gen_policy(principal_id, effect: str): return { "principalId": principal_id, "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": effect, "Resource": '*', } ], }, } authorizer.py
  9. -BNCEB"VUIPSJ[FS࣮૷  import boto3 def get_parameter_value(param_key): ssm = boto3.client('ssm') return

    ssm.get_parameter(Name=param_key, WithDecryption=True)['Parameter']['Value'] common.py