API Gateway Lambda 권한 부여자 사용 - Amazon API Gateway

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

API Gateway Lambda 권한 부여자 사용

Lambda 권한 부여자(이전 사용자 지정 권한 부여자)는 Lambda 함수를 사용하여 API 메서드에 대한 액세스를 제어하는 API Gateway 기능입니다.

Lambda 권한 부여자는 OAuth 또는 SAML과 같은 보유자 토큰 인증 전략을 사용하거나 요청 파라미터를 사용하여 호출자의 자격 증명을 확인하는 사용자 지정 인증 체계를 구현하려는 경우에 유용합니다.

클라이언트가 API의 메서드 중 하나를 요청할 경우 API Gateway는 해당 Lambda 권한 부여자를 호출합니다. 이 권한 부여자는 호출자의 자격 증명을 입력으로 받아서 IAM 정책을 출력으로 반환합니다.

Lambda 권한 부여자는 두 가지 유형이 있습니다.

  • 토큰 기반 Lambda 권한 부여자(TOKEN 권한 부여자라고도 함)는 보유자 토큰(JSON Web Token(JWT) 또는 OAuth 토큰)에 있는 호출자의 자격 증명을 받습니다. 예제 신청서는 오픈 뱅킹 브라질 - 승인 샘플 온을 참조하십시오 GitHub.

  • 요청 파라미터 기반 Lambda 권한 부여자(REQUEST 권한 부여자라고도 함)는 헤더, 쿼리 문자열 파라미터, stageVariables$context 변수의 조합으로 호출자의 자격 증명을 수신합니다.

    WebSocket API의 경우 요청 매개변수 기반 권한 부여자만 지원됩니다.

API를 생성한 계정과 다른 AWS 계정의 AWS Lambda 함수를 사용할 수 있습니다. 자세한 설명은 교차 계정 Lambda 권한 부여자 구성 섹션을 참조하세요.

Lambda 함수의 예는 -blueprints on을 참조하십시오. aws-apigateway-lambda-authorizer GitHub

Lambda 권한 부여자 인증 워크플로우

다음 다이어그램은 Lambda 권한 부여자에 대한 인증 워크플로를 보여 줍니다.


        API Gateway Lambda 권한 부여 워크플로
API Gateway Lambda 권한 부여 워크플로
  1. 클라이언트가 API Gateway API 메서드의 메서드를 호출하고 보유자 토큰이나 요청 파라미터를 전달합니다.

  2. API Gateway는 메서드에 대해 Lambda 권한 부여자가 구성되어 있는지 확인합니다. 구성되어 있으면 API Gateway가 Lambda 함수를 호출합니다.

  3. Lambda 함수는 다음과 같은 방법을 통해 호출자를 인증합니다.

    • OAuth 공급자를 호출하여 OAuth 액세스 토큰을 받습니다.

    • SAML 공급자를 호출하여 SAML 어설션을 받습니다.

    • 요청 파라미터 값을 기반으로 IAM 정책을 생성합니다.

    • 데이터베이스에서 자격 증명을 가져옵니다.

  4. 호출이 성공하면 Lambda 함수는 한 개 이상의 IAM 정책과 보안 주체 식별자를 포함하는 출력 객체를 반환하여 액세스를 부여합니다.

  5. API Gateway가 정책을 평가합니다.

    • 액세스가 거부되면 API Gateway는 적절한 HTTP 상태 코드(예: 403 ACCESS_DENIED)를 반환합니다.

    • 액세스가 허용되면 API Gateway가 메서드를 호출합니다. 권한 부여자 설정에서 캐싱이 활성화된 경우, API Gateway는 Lambda 권한 부여자 함수를 다시 호출할 필요가 없도록 정책을 캐싱합니다.

  6. Lambda 함수가 응답을 반환하는 경우 호출이 실패할 수 있습니다. 401 Unauthorized 401 Unauthorized게이트웨이 응답을 사용자 지정할 수 있습니다. 자세한 내용은 API Gateway의 게이트웨이 응답를 참조하세요.

API Gateway Lambda 권한 부여자 생성 단계

Lambda 권한 부여자를 생성하려면 다음 작업을 수행해야 합니다.

  1. Lambda 콘솔에서 API Gateway Lambda 권한 부여자 함수 생성에 설명된 대로 Lambda 콘솔에서 Lambda 권한 부여자 함수를 생성합니다. 블루프린트 예제 중 하나를 시작점으로 사용하여 입력출력을 원하는 대로 사용자 지정할 수 있습니다.

  2. API Gateway 콘솔을 사용하여 Lambda 권한 부여자 구성에서 설명한 대로 Lambda 함수를 API Gateway 권한 부여자로 구성하고, API 메서드가 이를 요구하도록 구성합니다. 또는 교차 계정 Lambda 권한 부여자가 필요할 경우 교차 계정 Lambda 권한 부여자 구성 단원을 참조하세요.

    참고

    AWS CLI 또는 AWS SDK를 사용하여 권한 부여자를 구성할 수도 있습니다.

  3. API Gateway Lambda 권한 부여자를 사용하여 API 호출에서 설명한 대로 Postman을 사용하여 권한 부여자를 테스트합니다.

Lambda 콘솔에서 API Gateway Lambda 권한 부여자 함수 생성

Lambda 권한 부여자를 구성하기 전에 먼저, 호출자를 권한 부여하고 필요한 경우 인증하기 위한 로직을 구현하는 Lambda 함수를 생성해야 합니다. Lambda 콘솔은 Python 블루프린트를 제공합니다. Python 블루프린트는 블루프린트 사용을 선택하고 블루프린트를 선택하여 사용할 수 있습니다. api-gateway-authorizer-python 그렇지 않으면, GitHub awslabs 리포지토리의 블루프린트 중 하나를 출발점으로 사용하는 것이 좋습니다.

이 단원에서 설명하는 Lambda 권한 부여자 함수 예제는 다른 서비스를 호출하지 않으므로 기본으로 제공되는 AWSLambdaBasicExecutionRole을 사용할 수 있습니다. 자체 API Gateway Lambda 권한 부여자를 위한 Lambda 함수를 생성할 때, 다른 서비스를 호출하는 경우 Lambda 함수에 IAM 실행 역할을 할당해야 합니다. AWS 역할을 생성하려면 AWS Lambda 실행 역할의 지침을 따르십시오.

Lambda 함수의 예시를 더 보려면 -blueprints on을 참조하십시오. aws-apigateway-lambda-authorizer GitHub 예제 애플리케이션은 오픈 뱅킹 브라질 - 인증 샘플 온을 참조하십시오. GitHub

예제: 토큰 기반의 Lambda 권한 부여자 함수 생성

토큰 기반의 Lambda 권한 부여자 함수를 만들려면 Lambda 콘솔에서 최근 런타임에 대해 다음 Node.js 코드를 입력합니다. 그런 다음 API Gateway 콘솔에서 권한 부여자를 테스트합니다.

토큰 기반 Lambda 권한 부여자 함수를 생성하려면
  1. Lambda 콘솔에서 함수 생성(Create function)을 선택합니다.

  2. 새로 작성을 선택합니다.

  3. 함수 이름을 입력합니다.

  4. 런타임에서 지원되는 최신 Node.js 또는 Python 런타임을 선택합니다.

  5. 함수 생성을 선택합니다.

  6. 다음 코드를 복사하여 코드 편집기에 붙여 넣습니다.

    Node.js
    // A simple token-based authorizer example to demonstrate how to use an authorization token // to allow or deny a request. In this example, the caller named 'user' is allowed to invoke // a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke // the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty // string, the authorizer function returns an HTTP 401 status code. For any other token value, // the authorizer returns an HTTP 500 status code. // Note that token values are case-sensitive. export const handler = function(event, context, callback) { var token = event.authorizationToken; switch (token) { case 'allow': callback(null, generatePolicy('user', 'Allow', event.methodArn)); break; case 'deny': callback(null, generatePolicy('user', 'Deny', event.methodArn)); break; case 'unauthorized': callback("Unauthorized"); // Return a 401 Unauthorized response break; default: callback("Error: Invalid token"); // Return a 500 Invalid token response } }; // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; } // Optional output with custom properties of the String, Number or Boolean type. authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; }
    Python
    # A simple token-based authorizer example to demonstrate how to use an authorization token # to allow or deny a request. In this example, the caller named 'user' is allowed to invoke # a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke # the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty # string, the authorizer function returns an HTTP 401 status code. For any other token value, # the authorizer returns an HTTP 500 status code. # Note that token values are case-sensitive. import json def lambda_handler(event, context): token = event['authorizationToken'] if token == 'allow': print('authorized') response = generatePolicy('user', 'Allow', event['methodArn']) elif token == 'deny': print('unauthorized') response = generatePolicy('user', 'Deny', event['methodArn']) elif token == 'unauthorized': print('unauthorized') raise Exception('Unauthorized') # Return a 401 Unauthorized response return 'unauthorized' try: return json.loads(response) except BaseException: print('unauthorized') return 'unauthorized' # Return a 500 error def generatePolicy(principalId, effect, resource): authResponse = {} authResponse['principalId'] = principalId if (effect and resource): policyDocument = {} policyDocument['Version'] = '2012-10-17' policyDocument['Statement'] = [] statementOne = {} statementOne['Action'] = 'execute-api:Invoke' statementOne['Effect'] = effect statementOne['Resource'] = resource policyDocument['Statement'] = [statementOne] authResponse['policyDocument'] = policyDocument authResponse['context'] = { "stringKey": "stringval", "numberKey": 123, "booleanKey": True } authResponse_JSON = json.dumps(authResponse) return authResponse_JSON
  7. 배포를 선택합니다.

Lambda 함수를 생성한 후 API Gateway 콘솔에서 토큰 기반 Lambda 권한 부여자를 생성하고 테스트합니다.

토큰 기반 Lambda 권한 부여자를 생성하려면
  1. 단순 API가 없을 경우 API Gateway 콘솔에서 만듭니다.

  2. API 목록에서 해당 API를 선택합니다.

  3. 권한 부여자를 선택합니다.

  4. 권한 부여자 생성을 선택합니다.

  5. 권한 부여자 이름에 이름을 입력합니다.

  6. 권한 부여자 유형으로 Lambda를 선택합니다.

  7. Lambda 함수의 경우, Lambda 권한 부여 함수를 생성한 위치를 선택한 다음 AWS 리전 함수 이름을 입력합니다.

  8. Lambda 호출 역할을 비워 둡니다.

  9. Lambda 이벤트 페이로드토큰을 선택합니다.

  10. 토큰 소스authorizationToken을 입력합니다.

  11. 권한 부여자 생성을 선택합니다.

권한 부여자를 테스트하려면
  1. 권한 부여자의 이름을 선택합니다.

  2. 테스트 권한 부여자에서 authorizationToken 값에 allow를 입력합니다.

  3. 테스트 권한 부여자를 선택합니다.

이 예제에서는 API가 메서드 요청을 받을 때 API Gateway가 소스 토큰을 이 Lambda 권한 부여자 함수의 event.authorizationToken 속성에 전달합니다. Lambda 권한 부여자 함수는 토큰을 읽고 다음과 같이 동작합니다.

  • 토큰 값이 'allow'인 경우 권한 부여자 함수 테스트는 200 OK HTTP 응답 및 다음과 같은 IAM 정책을 반환하고 메서드 요청이 성공합니다.

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
  • 토큰 값이 'deny'인 경우 권한 부여자 함수 테스트는 200 OK HTTP 응답 및 다음과 같은 Deny IAM 정책을 반환하고 메서드 요청이 실패합니다.

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Deny", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
    참고

    테스트 환경 밖에서는 권한 부여자 함수가 403 Forbidden HTTP 응답을 반환하고 메서드 요청이 실패합니다.

  • 토큰 값이 'unauthorized'이나 빈 문자열인 경우 권한 부여자 함수 테스트는 401 Unauthorized HTTP 응답을 반환하고 메서드 호출이 실패합니다.

  • 그 외 토큰의 경우 클라이언트는 500 Invalid token 응답을 수신하고, 메서드 호출은 실패합니다.

참고

프로덕션 코드에서는 권한 부여를 허용하기 전에 사용자를 인증해야 할 수 있습니다. 이 경우, 해당 공급자의 설명서에서 설명한 대로 인증 공급자를 호출하여 Lambda 함수에 인증 로직을 추가할 수 있습니다.

Lambda 권한 부여자 함수는 IAM 정책을 반환하는 것 외에 호출자의 보안 주체 ID도 반환해야 합니다. 선택적으로 통합 백엔드로 전달될 수 있는 추가 정보를 포함하는 context 객체를 반환할 수도 있습니다. 자세한 설명은 Amazon API Gateway Lambda 권한 부여자의 출력 섹션을 참조하세요.

예제: 요청 기반의 Lambda 권한 부여자 함수 생성

요청 기반의 Lambda 권한 부여자 함수를 만들려면 Lambda 콘솔에서 최근 런타임에 대해 다음 Node.js 코드를 입력합니다. 그런 다음 API Gateway 콘솔에서 권한 부여자를 테스트합니다.

  1. Lambda 콘솔에서 함수 생성(Create function)을 선택합니다.

  2. 새로 작성을 선택합니다.

  3. 함수 이름을 입력합니다.

  4. 런타임에서 지원되는 최신 Node.js 또는 Python 런타임을 선택합니다.

  5. 함수 생성을 선택합니다.

  6. 다음 코드를 복사하여 코드 편집기에 붙여 넣습니다.

    Node.js
    // A simple request-based authorizer example to demonstrate how to use request // parameters to allow or deny a request. In this example, a request is // authorized if the client-supplied headerauth1 header, QueryString1 // query parameter, and stage variable of StageVar1 all match // specified values of 'headerValue1', 'queryValue1', and 'stageValue1', // respectively. export const handler = function(event, context, callback) { console.log('Received event:', JSON.stringify(event, null, 2)); // Retrieve request parameters from the Lambda function input: var headers = event.headers; var queryStringParameters = event.queryStringParameters; var pathParameters = event.pathParameters; var stageVariables = event.stageVariables; // Parse the input for the parameter values var tmp = event.methodArn.split(':'); var apiGatewayArnTmp = tmp[5].split('/'); var awsAccountId = tmp[4]; var region = tmp[3]; var restApiId = apiGatewayArnTmp[0]; var stage = apiGatewayArnTmp[1]; var method = apiGatewayArnTmp[2]; var resource = '/'; // root resource if (apiGatewayArnTmp[3]) { resource += apiGatewayArnTmp[3]; } // Perform authorization to return the Allow policy for correct parameters and // the 'Unauthorized' error, otherwise. var authResponse = {}; var condition = {}; condition.IpAddress = {}; if (headers.headerauth1 === "headerValue1" && queryStringParameters.QueryString1 === "queryValue1" && stageVariables.StageVar1 === "stageValue1") { callback(null, generateAllow('me', event.methodArn)); } else { callback("Unauthorized"); } } // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { // Required output: var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; // default version policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; // default action statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; } // Optional output with custom properties of the String, Number or Boolean type. authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; } var generateAllow = function(principalId, resource) { return generatePolicy(principalId, 'Allow', resource); } var generateDeny = function(principalId, resource) { return generatePolicy(principalId, 'Deny', resource); }
    Python
    # A simple request-based authorizer example to demonstrate how to use request # parameters to allow or deny a request. In this example, a request is # authorized if the client-supplied headerauth1 header, QueryString1 # query parameter, and stage variable of StageVar1 all match # specified values of 'headerValue1', 'queryValue1', and 'stageValue1', # respectively. import json def lambda_handler(event, context): print(event) # Retrieve request parameters from the Lambda function input: headers = event['headers'] queryStringParameters = event['queryStringParameters'] pathParameters = event['pathParameters'] stageVariables = event['stageVariables'] # Parse the input for the parameter values tmp = event['methodArn'].split(':') apiGatewayArnTmp = tmp[5].split('/') awsAccountId = tmp[4] region = tmp[3] restApiId = apiGatewayArnTmp[0] stage = apiGatewayArnTmp[1] method = apiGatewayArnTmp[2] resource = '/' if (apiGatewayArnTmp[3]): resource += apiGatewayArnTmp[3] # Perform authorization to return the Allow policy for correct parameters # and the 'Unauthorized' error, otherwise. authResponse = {} condition = {} condition['IpAddress'] = {} if (headers['headerauth1'] == "headerValue1" and queryStringParameters["QueryString1"] == "queryValue1" and stageVariables["StageVal1"] == "stageValue1"): response = generateAllow('me', event['methodArn']) print('authorized') return json.loads(response) else: print('unauthorized') raise Exception('Unauthorized') # Return a 401 Unauthorized response return 'unauthorized' # Help function to generate IAM policy def generatePolicy(principalId, effect, resource): authResponse = {} authResponse['principalId'] = principalId if (effect and resource): policyDocument = {} policyDocument['Version'] = '2012-10-17' policyDocument['Statement'] = [] statementOne = {} statementOne['Action'] = 'execute-api:Invoke' statementOne['Effect'] = effect statementOne['Resource'] = resource policyDocument['Statement'] = [statementOne] authResponse['policyDocument'] = policyDocument authResponse['context'] = { "stringKey": "stringval", "numberKey": 123, "booleanKey": True } authResponse_JSON = json.dumps(authResponse) return authResponse_JSON def generateAllow(principalId, resource): return generatePolicy(principalId, 'Allow', resource) def generateDeny(principalId, resource): return generatePolicy(principalId, 'Deny', resource)
  7. 배포를 선택합니다.

Lambda 함수를 생성한 후 API Gateway 콘솔에서 요청 기반 Lambda 권한 부여자를 생성하고 테스트합니다.

요청 기반 Lambda 권한 부여자를 생성하려면
  1. 단순 API가 없을 경우 API Gateway 콘솔에서 만듭니다.

  2. API 목록에서 해당 API를 선택합니다.

  3. 권한 부여자를 선택합니다.

  4. 권한 부여자 생성을 선택합니다.

  5. 권한 부여자 이름에 이름을 입력합니다.

  6. 권한 부여자 유형으로 Lambda를 선택합니다.

  7. Lambda 함수의 경우, Lambda 권한 부여 함수를 생성한 위치를 선택한 다음 AWS 리전 함수 이름을 입력합니다.

  8. Lambda 호출 역할을 비워 둡니다.

  9. Lambda 이벤트 페이로드요청을 선택합니다.

  10. 자격 증명 소스 유형에서 다음을 입력합니다.

    1. 헤더를 선택하고 headerauth1을 입력한 다음 파라미터 추가를 선택합니다.

    2. 자격 증명 소스 유형에서 쿼리 문자열을 선택한 다음 QueryString1을 입력하고 파라미터 추가를 선택합니다.

    3. 자격 증명 소스 유형에서 스테이지 변수를 선택하고 StageVar1을 입력합니다.

  11. 권한 부여자 생성을 선택합니다.

권한 부여자를 테스트하려면
  1. 권한 부여자의 이름을 선택합니다.

  2. 테스트 권한 부여자에서 다음을 입력합니다.

    1. 헤더를 선택하고 headerValue1을 입력한 다음 파라미터 추가를 선택합니다.

    2. 자격 증명 소스 유형에서 쿼리 문자열을 선택한 다음 queryValue1을 입력하고 파라미터 추가를 선택합니다.

    3. 자격 증명 소스 유형에서 스테이지 변수를 선택하고 stageValue1을 입력합니다.

  3. 테스트 권한 부여자를 선택합니다.

이 예제에서 Lambda 권한 부여자 함수는 입력 파라미터를 확인하고 다음과 같이 동작합니다.

  • 필요한 모든 파라미터 값이 예상 값과 일치하면 권한 부여자 함수가 200 OK HTTP 응답 및 다음과 같은 IAM 정책을 반환하고 메서드 요청이 성공합니다.

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
  • 일치하지 않으면 권한 부여자 함수가 401 Unauthorized HTTP 응답을 반환하고 메서드 호출이 실패합니다.

참고

프로덕션 코드에서는 권한 부여를 허용하기 전에 사용자를 인증해야 할 수 있습니다. 이 경우, 해당 공급자의 설명서에서 설명한 대로 인증 공급자를 호출하여 Lambda 함수에 인증 로직을 추가할 수 있습니다.

Lambda 권한 부여자 함수는 IAM 정책을 반환하는 것 외에 호출자의 보안 주체 ID도 반환해야 합니다. 선택적으로 통합 백엔드로 전달될 수 있는 추가 정보를 포함하는 context 객체를 반환할 수도 있습니다. 자세한 설명은 Amazon API Gateway Lambda 권한 부여자의 출력 섹션을 참조하세요.