Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ユースケースで学ぶ!API Gateway + Lambda Authorizer 実践入門(...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Shiraishi
July 26, 2022
Technology
2.1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ユースケースで学ぶ!API Gateway + Lambda Authorizer 実践入門(CDK)
Shiraishi
July 26, 2022
Other Decks in Technology
See All in Technology
從開發到部署全都交給 AI:實作 AI 驅動的自動化流程
appleboy
0
150
SONiCで構築・運用する生成AI向けパブリッククラウドネットワーク ~実装編~
sonic
0
340
生成 AI 実践ガイド (概略版) AIガバナンス編
asei
0
190
飲食店もAIで。レジ締めやハンディシステムをつくってる話 / Using AI for restaurant management
vtryo
0
150
SONiCのLinuxベースを活かしたZabbix監視
sonic
0
290
Claude Codeをどのように キャッチアップしているか
oikon48
13
8.8k
新しいUbuntu/GNOMEが使いたいからXからWaylandへ移行頑張ってるの巻 2026-06-20
nobutomurata
0
160
Lightning近況報告
kozy4324
0
220
IaC コードを資産へ:AWS CDK 社内ライブラリと横断展開 / aws-summit-japan-2026
gotok365
10
1.6k
2026-06-24_人とAIの責務分離に基づく開発プロセスの提案.pdf
takahiromatsui
0
120
AI 不只幫你寫 Code: 當專案從 300 暴增到 1500, 我們如何撐住 DevOps
appleboy
0
210
データレイクの「見えない問題」を可視化する
sansantech
PRO
1
200
Featured
See All Featured
Paper Plane
katiecoart
PRO
1
52k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Speed Design
sergeychernyshev
33
1.9k
Faster Mobile Websites
deanohume
310
32k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
200
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
BBQ
matthewcrist
89
10k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
250
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
The Mindset for Success: Future Career Progression
greggifford
PRO
0
370
Transcript
ϢʔεέʔεͰֶͿʂ "1*(BUFXBZ -BNCEB"VUIPSJ[FS࣮ೖʢ$%,ʣ "84ࣄۀຊ෦ίϯαϧςΟϯά෦നੴҰ
ࣗݾհ w"84ࣄۀຊ෦ίϯαϧς Οϯά෦ w"84ΤϯδχΞ ϑϩϯτ ΤϯυΤϯδχΞ w8FCडୗ4&4$. w"84 )5.-
$44 +BWB4DSJQU 5ZQF4DSJQU 1)1 1FSM $ 1ZUIPO നੴҰʢShiraishi Seiichiʣ
ΞδΣϯμ ຊηογϣϯʹ͍ͭͯ ࣮֓ཁʢ8FCIPPL #BTJDೝূར༻ʣ "1*(BUFXBZ -BNCEB"VUIPSJ[FS࣮ ·ͱΊ
ΞδΣϯμ ຊηογϣϯʹ͍ͭͯ ࣮֓ཁʢ8FCIPPL #BTJDೝূར༻ʣ "1*(BUFXBZ -BNCEB"VUIPSJ[FS࣮ ·ͱΊ
ຊηογϣϯʹ͍ͭͯ ରࢹௌऀ w"1*։ൃॳֶऀ w"1*(BUFXBZ -BNCEB"VUIPSJ[FSॳֶऀ ΰʔϧ w8FCIPPLΛड͚͚ΔͨΊͷ"1*(BUFXBZΛ࣮͠·͢ɻ"1* (BUFXBZʹ#BTJDೝূΛ࣮͠·͢ɻ w͜ͷྫΛ௨ͯ͠ɺԿ͔ಘΔͷ͕͋Γ·͢ͱ͍Ͱ͢ɻ
ຊηογϣϯʹೖΔલʹ લఏ݅ wຊηογϣϯͰɺ;FOEFTLʹͯ8FCIPPLͷઃఆΛߦ͍ɺ 8FCIPPLΛड͚͚Δ"1*Λ࡞͢Δํ๏Λ͝հ͠·͢ɻ w;FOEFTLଆͷઃఆऔΓѻΘͣɺࢀߟϒϩάͷ͝հͷΈͱͤͯ͞ ͍͖ͨͩ·͢ɻ ༻͢Δٕज़ w"1*(BUFXBZ -BNCEB"VUIPSJ[FS
w"84$%,W
ΞδΣϯμ ຊηογϣϯʹ͍ͭͯ ࣮֓ཁʢ8FCIPPL #BTJDೝূར༻ʣ "1*(BUFXBZ -BNCEB"VUIPSJ[FS࣮ ·ͱΊ
࣮֓ཁ w;FOEFTLͷ8FCIPPLઃఆ w;FOEFTLͷ#BTJDೝূઃఆ w8FCIPPLΛड͚͚Δ"1*ͷ࡞ w"1*(BUFXBZͷ࡞ w-BNCEB"VUIPSJ[FSͷ࡞
࣮֓ཁ w;FOEFTLͱ w;FOEFTLɺʮ͓٬༷͕৺Α͍ͱײ͡ΔΤΫεϖϦΤϯεʯΛ࣮ ݱ͢ΔΧελϚʔαʔϏεϓϥοτϑΥʔϜΛఏڙ͍ͯ͠·͢ɻ ϝʔϧ͔Βͷ͓͍߹Θͤɺνϟοτ͔Βͷ͓͍߹ΘͤҰݩ ཧͰ͖ΔͨΊɺΧελϚʔαʔϏεۀ͕ܶతʹεϜʔζʹͳΔ ͱͱʹɺސ٬ͱͷΑΓྑ͍ؔΛங͘͜ͱ͕ՄೳʹͳΓ·͢ɻ wҾ༻ɿIUUQTXXX[FOEFTLDPKQBCPVU
࣮֓ཁ w"1*(BUFXBZͱ w"NB[PO"1*(BUFXBZɺ͋ΒΏΔنͷ3&45ɺ)551ɺ͓Α ͼ8FC4PDLFU"1*Λ࡞ɺެ։ɺҡ࣋ɺϞχλϦϯάɺ͓Αͼη ΩϡΞԽ͢ΔͨΊͷ"84ͷαʔϏεͰ͢ɻ wҾ༻ɿIUUQTEPDTBXTBNB[PODPNKB@KQBQJHBUFXBZ MBUFTUEFWFMPQFSHVJEFXFMDPNFIUNM
࣮֓ཁ w-BNCEB"VUIPSJ[FSͱ w-BNCEBؔΛ༻ͯ͠)551"1*ͷΞΫηεΛ੍ޚ͢Δ ΈͰ͢ɻ wҾ༻ɿIUUQTEPDTBXTBNB[PODPNKB@KQBQJHBUFXBZ MBUFTUEFWFMPQFSHVJEFIUUQBQJMBNCEBBVUIPSJ[FSIUNM
ΞʔΩςΫνϟ
ΞδΣϯμ ຊηογϣϯʹ͍ͭͯ ࣮֓ཁʢ8FCIPPL #BTJDೝূར༻ʣ "1*(BUFXBZ -BNCEB"VUIPSJ[FS࣮ ·ͱΊ
;FOEFTLଆઃఆ https://dev.classmethod.jp/ articles/zendesk-attachments- to-s3/ wʮ;FOEFTLͷ8FCIPPLͱ τϦΨʔͷઃఆʯͷষΛࢀߟ
"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’) ] })
"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, })
-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] });
-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] });
-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);
-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
-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
-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
ʢ͓·͚ʣ8FCIPPLॺ໊ݕূ common.py https://dev.classmethod.jp/ articles/zendesk-webhook- signature-veri fi cation-in-python/ wηΩϡϦςΟରࡦͱͯ͠ 8FCIPPL͕ຊʹ;FOEFTL
͔ΒͷͷͰ͋Δ͔Ͳ͏͔Λ֬ ೝɾݕূ͢Δ
ΞδΣϯμ ຊηογϣϯʹ͍ͭͯ ࣮֓ཁʢ8FCIPPL #BTJDೝূར༻ʣ "1*(BUFXBZ -BNCEB"VUIPSJ[FS࣮ ·ͱΊ
·ͱΊ w$%, -BNCEB"VUIPSJ[FSϦϑΝϨϯεΛಡΈ࣮͠·͠ΐ͏ wIUUQTEPDTBXTBNB[PODPNKB@KQBQJHBUFXBZMBUFTU EFWFMPQFSHVJEFBQJHBUFXBZVTFMBNCEBBVUIPSJ[FSIUNM w8FCIPPLΛར༻࣮ͨ͠ɺ;FOEFTLʹݶΒͣଞͷαʔϏεͰΑ ͋͘ΔͨΊྲྀ༻Ͱ͖Δʢ4MBDL %JTDPSE -*/&FUDʣ
wૉৼΓͱͯ͠ɺ͓खܰͳϢʔεέʔε
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
None