AWS API 게이트웨이 WebSocket API의 쿠키 인증


모티프
본고는 메인 웹 응용 프로그램이 쿠키를 사용하여 신분 검증과 권한 수여를 할 때 AWS Api Gateway에서 Websocket API의 신분 검증과 권한 수여의 구체적인 사례를 기술하고자 한다.
이 글을 쓰는 순간, 나는 한 곳에서 모든 정보를 찾을 수 없었다. 나는 몇 가지 시도와 오류를 써서 이 수수께끼의 모든 부분을 결국 한데 묶었다.

문제.
사용자가 프런트엔드에 로그인하면 두 개의 쿠키를 보내는 백엔드가 있습니다.
  • JWT(보안, http 전용)
  • CSRF-TOKEN(보안)
    (이것은 흔히 볼 수 있는 방법으로double submit cookie모델이라고 한다.)
  • 여기서 JWT는 http 전용 쿠키로서 브라우저에서 JavaScript를 통해 액세스할 수 없습니다.
    이것은 웹 소켓 연결을 열고 메시지에 이 두 개의 영패를 동시에 보낼 수 없다는 것을 의미한다.
    한편, 기본적으로 API Gateway websocket API의 URL 형식은 wss://{YOUR-API-ID}입니다.api를 실행합니다.{지역}.아마존com/{STAGE},
    이것은 프로그램의 영역이 다르기 때문에 $connect route integration에 쿠키를 보내지 않습니다. (예: ui. {environment}. yourapplication.com)
    HTTP 요청을 만들지 않기 때문에 $connect route에 대해 $default, $disconnect, 사용자 정의 루트만 언급했습니다.

    솔루션

    사용자 정의 도메인 이름
    첫 번째 문제는 쿠키를 $connect route integration에 보내는 것입니다.이 작업은 API 게이트웨이custom domain names 기능을 사용하여 수행할 수 있습니다.
    이것은 ws 형식으로 도메인을 만드는 것과 관련이 있습니다.{환경}.너의 신청.com 또는 다른 접두사, 이 접두사는 사용자 인터페이스와 공공 부분인 '{environment}. yourapplication.com' 을 가지고 있습니다.
    너는 창조해야 한다
  • AWS:ApiGateway V2::도메인 이름
  • AWS::ApiGatewayV2::ApiMapping
  • AWS::Route53::RecordSet(CNAME)
  • 이 섹션은 AWS 문서에 설명되어 있으며 사용자 구성에 따라 세부내용이 달라집니다.
    백엔드에서 쿠키의 영역을 변경하는 것을 잊지 마십시오. 공공 부분 '{environment}. yourapplication.com' 과 일치하고 호스트만 일치하지 않습니다. (set 쿠키 헤더에 설정해야 합니다. Domain attribute

    Lambda 권한 수여자
    AWS는 API Gateway의 WebSocket을 통해 사용자를 인증하는 방식으로 lambda 권한 수여 프로그램을 제공하지만, 백엔드에서 쿠키에서 사용자 정보를 어떻게 얻는지 모든 지식을 습득했기 때문에 이 작업을 백엔드에 의뢰하는 것은 논리적인 것 같다.
    단, 쿠키를 HTTP나 VPC 통합에 직접 전달하면 백엔드에서 연결을 취소하거나 $connect 루트에 분배된 단점에서 웹소켓 메시지를 보낼 수 없습니다. 웹소켓 연결은 통합이 발생하기 전에 만들어졌기 때문입니다.
    만약 당신이 lambda 통합을 가지고 있다면, 이론적으로 auth 오류를 던질 수 있습니다. 웹 소켓 연결은 발생하지 않을 것입니다.이것은 나의 사건이 아니기 때문에, 나는 lambda 권한 수여인을 사용해야 한다.
    AWS 문서와 well, and node에 명확한 예시 alambda authorizer가 있다.js는 시간이 짧고 함수의 계산이 상대적으로 간단하기 때문에 좋은 선택인 것 같다.
    cloudformation 템플릿에서 이 함수를 내연적으로 작성하려면 문자의 제한이 cold start 이고, 'aws sdk/clients/ssm' (JS sdk v2) 과 'crypto' 같은 패키지를 사용할 수 있습니다. 4096 에서 사용할 수 있기 때문에 패키지를 만들 필요가 없습니다.json;
    실행 중인 lambda가 다시 사용되지 않도록 handler 함수 외에 ssm와 다른aws 클라이언트를 초기화해야 합니다.
    만약 lambda 권한 수여기 논리가 환경에 의존하지 않는다면, AWS의 건의에 따라 단독 창고에 두는 것도 의미가 있습니다. 즉, 창고의 생명주기에 따라 창고를 구성하는 것입니다.
    그런 다음, API 스위치가 있는 템플릿에서 lambda를 인용하거나, 매개 변수에서 lambda 버전을 전달하고, 이 lambda를 변경할 때 매개 변수를 업데이트할 수 있습니다.모든 환경에 별명을 만들 수 있습니다. 이 lambda를 사용하는 창고에서 lambda 버전을 업데이트할 필요가 없고, 이 lambda 창고를 업데이트해서 별명을 특정 버전으로 가리킬 수 있습니다.
    최소 lambda 창고에서 만들어야 합니다

    1 . AWS::Lambda::Function

    2 . AWS::IAM::Role which will be assumed to execute the lambda
    with AssumeRolePolicyDocument:

    Version: "2012-10-17"
    Statement:
    -
     Effect: "Allow"
     Principal:
       Service:
         - "lambda.amazonaws.com"
     Action:
       - "sts:AssumeRole"
    

    and ManagedPolicyArns:

    - 'arn:aws:iam::aws:policy/service->role/AWSLambdaBasicExecutionRole'
    

    and Policies necessary for your lambda to have access to ssm or >any other services used inside lambda. Make sure to follow the >least privilege principle giving these permissions

    3 . AWS::Lambda::Version

    4 . AWS::Logs::LogGroup in case you have logging


    API 게이트웨이 스택에서 생성 필요

    1 . AWS::ApiGatewayV2::Authorizer
    make sure AuthorizerUri is in the correct format

       !Join
       - ''
       - - 'arn:'
           - !Ref 'AWS::Partition'
           - ':apigateway:'
           - !Ref 'AWS::Region'
           - ':lambda:path/2015-03-31/functions/'
           - !Ref YourLambdaVerionArn
           - /invocations
    

    and IdentitySource:

    - route.request.header.Cookie
    

    which is used as a caching key. Auth result is cached for 300 seconds by default

    2 . AWS::Lambda::Permission for the authorizer to call your lambda

    3 . Change in the AWS::ApiGatewayV2::Route to use your authorizer

    4 . Change your RequestTemplate on $connect route integration to pass all the necessary authorization info from an authorizer (i.e. $context.authorizer.principalId)


    JWT와 CSRF-TOKEN을 추출하려면 쿠키 헤더의 값을 분석해야 합니다. 이 값은 모든 쿠키를 포함하기 때문입니다.
    CloudFormation을 통해 배치를 만들면, CloudFormation 템플릿의 DependsOn 속성에 필요한 모든 자원을 추가하십시오. 특히 API 게이트웨이 배치는 정확한 순서로 자원을 만들 수 있도록 하십시오.
    나는 이 문장이 같은 문제에 직면한 사람들에게 도움이 될 수 있기를 바란다.

    좋은 웹페이지 즐겨찾기