본문 바로가기
자습

JWT and API Gateway Lambda Authorizer

by litaro 2019. 11. 23.

https://medium.com/swlh/how-to-protect-apis-with-jwt-and-api-gateway-lambda-authorizer-1110ff035df1

 

How to protect APIs with JWT and API Gateway Lambda Authorizer

This story is about API Gateway Lambda Authorizer’s concepts: how it works, why it works that way and how we can leverage it. Enjoy :)

medium.com

JSON Web Token (JWT) 은 authentication 과 authorization을 위한 정보 전송에 관한 표준 (RFC 7519)

참고: https://litaro.tistory.com/entry/JWT-in-the-modern-web

위의 시나리오에서 JWT token이 없다면, 1,2,3 을 resource server (API Gateway) 에 요청하기 전에 매번 거져야 할것이다.

하지만 한번 발급받은 JWT token이 있으면 바로 4,5,6 으로 갈수 있다.

그럼 이것을 실제로 구현 해보자

Framing the context

https://medium.com/swlh/how-to-protect-apis-with-jwt-and-api-gateway-lambda-authorizer-1110ff035df1

AWS에서 구성한 간단한 REST 서버 구조

  • the HTTP REST endpoint : API Gateway
  • the endpoint’s backend : Lambda (containerized microservice, load balancer, HTTP endpont...)

어디에서 token 체크를 하지?

cowboy's logic 은 그냥 backend에 바로 넣으려고 할것이다.

모. 하나의 서비스 서버로 구현한다면 안될것도 없다

하지만 요즘은 microservices 시대. 아래와같이 Auth Logic이 Business Logic과 같이 있다면 비효율적이다. (Auth Logic 버그 하나 생기면 모두 배포해야..)

그러니 Auth Logic을 Business Logic에서 분리해내서 Auth Logic만 전담하는 서비스를 만들자

이제 Auth Logic 수정이 필요하면 해당 서비스만 다시 배포하면 된다.

Fig. 2를 다시 보면,

바로 Business Logic 이 들어 있는 Lambda를 API Gateway에 연결하지 말고 중간에 authorization 담당 서비스를 넣는것이 좋다는것을 알수 있다.

Introducing Lambda Authorizer

Lambda Authorizer 는 특이한 타입의 Lambda 이다.

token 이 담긴 object를 받아서 아래와 같은 JSON policy를 리턴한다.

해당 policy를 해석하면,

principalId 가 "apigateway.amazonaws.com"인 API Gateway가 

ARN이 "arn:aws:execute-api:{REGION}:{ACCOUNT_ID}:{API_ID}/Prod/GET/" 인 API Resource를 실행하는 것을 Allow 한다는것이다.

 

이러한 Policy를 내보내기 위해서는 들어오는 Token을 verify해야한다.

token 정보는 아래와 같이 lambda 의 evnet 객체에 들어오게 된다. 

  • event.authorizationToken — the token we want to verify;
  • event.methodArn— the ARN of the API request that triggered the authorizer;

Our first Lambda Authorizer

간단한 Lambda Authorizer 로직을 코드로 보면

event로 들어온 autorizationToken 값이 "OK"이면 allowPolicy가 나가고 아니면 denyPolicy가 나간다.

Creating our first Lambda Authorizer

1. Authorization logic이 있는 lambda 함수를 생성한다.

여기 블로그에서는 AWS CodeStar로 프로젝트를 만들었는데.. CodeStar 프로젝트를 만드려면 IAM administrative user 로 로그인해서 Service role을 만들어야 한다.

2. API Gateway Console에서 Authorizers 를 설정한다.

 Authorizers” tab의 “Create New Authorizer” 를 click한다.

Name 설정하고 Type 은 Lambda를 선택한다.

Lambda Funciton은 Step 1 에서 만든 Lambda ARN을 넣는다.

그리고 Event는 Token을 선택한다.

관습적으로 token은 "Authorization" HTTP header 를 통해 보내기 때문에  Token Source를 "Authorization"로 설정한다.

그리고 "Create" 하면 아래와 같이 Lambda를 invoke하기 위한 permission을 grant 하는 pop up이 뜬다.

“Grant & Create” 클릭

Test를 위해 "NOT OK"를 Authoization에 넣으면 예상대로 DenyPolicy가 Return된다.

Wire everything together

Resources에는 Business Logic이 있는 Lambda를 연결한다.

이때 Method Request 를 click해서 Authorization 에서 위에서 만든 Lambda Authorizer를 선택하여 설정한다.

Deploy and test the modifications

완료 되면 Deploy (Actions > Deploy API) 하여 나오는 Invoke URL로 Postman으로 테스트 진행한다.

A real authorizer

위의 예제는 이해를 돕기위한 것이고 실제 Authorizer의 로직을 살펴보자

  • Toekn을 decode해서 endpoint 를 찾아야한다.
  • endpoint를 invoke해서 kid 정보를 이용해서 public key를 얻기 위한 exponent 와 modulus 를 찾아야 한다.
  • PEM을 계산하고
  • PEM과 token을 Verify 한다.

pseudo code: https://medium.com/swlh/how-to-protect-apis-with-jwt-and-api-gateway-lambda-authorizer-1110ff035df1

Summary

JWT를 AWS Echo system (API Gateway + Lambda Authorizer) 를 활용하여 어떻게 사용하는지 간단하게 살펴보았다.

위 기능을 통해 Business Logic에서 Authorization Logic을 분리해 낼수 있다.

한번 경험하고 싶으면 https://github.com/marianoc84/lambda-authorizers-collections 코드를 참조