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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
Compose 新機能総まとめ / What's New in Jetpack Compose
yanzm
0
320
アップデートで何が変わった?デモで学んで使いこなすIBM Bob2.0
muehara
0
110
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.4k
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
260
ガバナンスの「ちょうどいい落とし所」を探れ!開発スピードを妨げない運用判断の勘所 / SRE NEXT 2026
genda
1
240
穢れた技術選定について
watany
17
5.4k
ボーイスカウトルールでメモリやスキルを改善しよう
azukiazusa1
4
1.4k
SoccerMaster: A Vision Foundation Model for Soccer Understanding
kzykmyzw
0
130
LLM/Agent評価:トップ営業の発言を「正解」にする 〜暗黙的正解による評価を営業資産に変える〜
takkuhiro
1
230
美しいコードを書くためにF#を学んでみた話
yud0uhu
1
460
見守りエージェントを作ってみた(ローカルLLM + Hermes Agent)
happysamurai294
0
110
「最後に責任を取るのはチーム」— 人間のPRレビューを最小化してアップデートしたメンタルモデル
jnishime_dresscode
0
880
Featured
See All Featured
Docker and Python
trallard
47
4k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Deep Space Network (abreviated)
tonyrice
0
230
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Accessibility Awareness
sabderemane
1
160
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
220
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
200
Making the Leap to Tech Lead
cromwellryan
135
10k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
220
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