

# API Gateway Lambda 권한 부여자 사용
<a name="apigateway-use-lambda-authorizer"></a>

*Lambda 권한 부여자*(이전 *사용자 지정 권한 부여자*)를 사용하여 API에 대한 액세스를 제어할 수 있습니다. 클라이언트가 API의 메서드를 요청하면 API Gateway는 Lambda 권한 부여자를 직접적으로 호출합니다. Lambda 권한 부여자는 호출자의 자격 증명을 입력으로 사용하고 IAM 정책을 출력으로 반환합니다.

Lambda 권한 부여자를 사용하여 사용자 지정 권한 부여 체계를 구현할 수 있습니다. 이 체계는 요청 파라미터를 사용하여 호출자의 자격 증명을 확인하거나 OAuth 또는 SAML과 같은 보유자 토큰 인증 전략을 사용할 수 있습니다. AWS CLI 또는 AWS SDK를 사용하여 API Gateway REST API 콘솔에서 Lambda 권한 부여자를 생성합니다.

## Lambda 권한 부여자 인증 워크플로
<a name="api-gateway-lambda-authorizer-flow"></a>

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

![\[API Gateway Lambda 권한 부여 워크플로\]](http://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/images/custom-auth-workflow.png)


**API Gateway Lambda 권한 부여 워크플로**

1. 클라이언트가 API Gateway API의 메서드를 직접적으로 호출하고 보유자 토큰 또는 요청 파라미터를 전달합니다.

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

1. Lambda 함수가 호출자를 인증합니다. 이 함수는 다음과 같은 방식으로 인증될 수 있습니다.
   + OAuth 공급자를 직접적으로 호출하여 OAuth 액세스 토큰을 받습니다.
   + SAML 공급자를 직접적으로 호출하여 SAML 어설션을 받습니다.
   + 요청 파라미터 값을 기반으로 IAM 정책을 생성합니다.
   + 데이터베이스에서 자격 증명을 가져옵니다.

1. Lambda 함수가 IAM 정책과 보안 주체 식별자를 반환합니다. Lambda 함수가 해당 정보를 반환하지 않으면 직접 호출이 실패합니다.

1. API Gateway가 IAM 정책을 평가합니다.
   + 액세스가 거부되면 API Gateway는 적절한 HTTP 상태 코드(예: `403 ACCESS_DENIED`)를 반환합니다.
   + 액세스가 허용되면 API Gateway가 메서드를 간접 호출합니다.

     권한 부여 캐싱이 활성화된 경우, API Gateway는 Lambda 권한 부여자 함수가 다시 간접적으로 호출되지 않도록 정책을 캐싱합니다. 정책이 API의 모든 리소스 및 메서드에 적용 가능한지 확인합니다.

`403 ACCESS_DENIED` 또는 `401 UNAUTHORIZED` 게이트웨이 응답을 사용자 지정할 수 있습니다. 자세한 내용은 [API Gateway의 REST API에 대한 게이트웨이 응답](api-gateway-gatewayResponse-definition.md)를 참조하세요.

## Lambda 권한 부여자 유형 선택
<a name="api-gateway-lambda-authorizer-choose"></a>

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

**요청 파라미터 기반 Lambda 권한 부여자(`REQUEST` 권한 부여자)**  
`REQUEST` 권한 부여자는 헤더, 쿼리 문자열 파라미터, [`stageVariables`](api-gateway-mapping-template-reference.md#stagevariables-template-reference), [`$context`](api-gateway-mapping-template-reference.md#context-variable-reference) 변수 조합에 있는 직접 호출자 자격 증명을 받습니다. `REQUEST` 권한 부여자를 사용하여 `$context.path` 및 `$context.httpMethod` 컨텍스트 변수와 같은 여러 자격 증명 소스의 정보를 기반으로 세분화된 정책을 생성할 수 있습니다.  
`REQUEST` 권한 부여자에 대한 권한 부여 캐싱을 켜면 API Gateway는 요청에 지정된 모든 자격 증명 소스가 있는지 확인합니다. 지정된 자격 증명 소스가 없거나, null이거나, 비어 있을 경우 API Gateway가 Lambda 권한 부여자 함수를 호출하지 않고 `401 Unauthorized` HTTP 응답을 반환합니다. 여러 개의 자격 증명 소스가 정의된 경우, 이들은 순서가 유지된 상태로 모두 권한 부여자의 캐시 키를 도출하는 데 사용됩니다. 여러 자격 증명 소스를 사용하여 세분화된 캐시 키를 정의할 수 있습니다.  
캐시 키 부분을 변경하고 API를 재배포하면 권한 부여자가 캐시된 정책 문서를 폐기하고 새로 생성합니다.  
`REQUEST` 권한 부여자에 대한 권한 부여 캐싱을 끄면 API Gateway가 요청을 Lambda 함수에 직접 전달합니다.

**토큰 기반 Lambda 권한 부여자(`TOKEN` 권한 부여자)**  
`TOKEN` 권한 부여자는 보유자 토큰(JSON Web Token(JWT) 또는 OAuth 토큰)에 있는 호출자의 자격 증명을 받습니다.  
`TOKEN` 권한 부여자에 대한 인증 캐싱을 켜는 경우 토큰 소스에 지정된 헤더 이름이 캐시 키가 됩니다.  
또한 토큰 검증을 사용하여 정규 표현식 문을 입력할 수 있습니다. API Gateway는 이 표현식에 대해 입력 토큰의 초기 검증을 수행하고 검증에 성공할 경우 Lambda 권한 부여자 함수를 간접적으로 호출합니다. 이렇게 하면 API 호출을 줄일 수 있습니다.  
`IdentityValidationExpression` 속성은 `TOKEN` 권한 부여자에만 지원됩니다. 자세한 내용은 [x-amazon-apigateway-authorizer 객체](api-gateway-swagger-extensions-authorizer.md) 섹션을 참조하세요.

**참고**  
`REQUEST` 권한 부여자를 사용하여 API에 대한 액세스를 제어하는 것이 좋습니다. `TOKEN` 권한 부여자를 사용할 때는 단일 자격 증명 소스를 기반으로 하지만 `REQUEST` 권한 부여자를 사용할 때는 여러 자격 증명 소스를 기반으로 하여 API에 대한 액세스를 제어할 수 있습니다. 또한 `REQUEST` 권한 부여자의 경우 여러 자격 증명 소스를 사용하여 캐시 키를 분리할 수 있습니다.

## `REQUEST` 권한 부여자 Lambda 함수 예제
<a name="api-gateway-lambda-authorizer-request-lambda-function-create"></a>

다음 예제 코드는 클라이언트가 제공한 `HeaderAuth1` 헤더, `QueryString1` 쿼리 파라미터 및 스테이지 변수 `StageVar1`이 모두 `headerValue1`, `queryValue1`, `stageValue1`의 지정된 값과 각각 일치하는 경우 요청을 허용하는 Lambda 권한 부여 함수를 생성합니다.

------
#### [ 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.

     
    if (headers.HeaderAuth1 === "headerValue1"
        && queryStringParameters.QueryString1 === "queryValue1"
        && stageVariables.StageVar1 === "stageValue1") {
        callback(null, generateAllow('me', event.methodArn));
    }  else {
        callback(null, generateDeny('me', event.methodArn));
    }
}
     
// 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.

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.

    if (headers['HeaderAuth1'] == "headerValue1" and queryStringParameters['QueryString1'] == "queryValue1" and stageVariables['StageVar1'] == "stageValue1"):
        response = generateAllow('me', event['methodArn'])
        print('authorized')
        return response
    else:
        print('unauthorized')
        response = generateDeny('me', event['methodArn'])
        return response
    # 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
    }

    return authResponse


def generateAllow(principalId, resource):
    return generatePolicy(principalId, 'Allow', resource)


def generateDeny(principalId, resource):
    return generatePolicy(principalId, 'Deny', resource)
```

------

이 예제에서 Lambda 권한 부여자 함수는 입력 파라미터를 확인하고 다음과 같이 동작합니다.
+ 필요한 모든 파라미터 값이 예상 값과 일치하면 권한 부여자 함수가 `200 OK` HTTP 응답 및 다음과 같은 IAM 정책을 반환하고 메서드 요청이 성공합니다.

------
#### [ JSON ]

****  

  ```
  {
    "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 권한 부여자 함수는 IAM 정책을 반환하는 것 외에 호출자의 보안 주체 ID도 반환해야 합니다. 선택적으로 통합 백엔드로 전달될 수 있는 추가 정보를 포함하는 `context` 객체를 반환할 수 있습니다. 자세한 내용은 [API Gateway Lambda 권한 부여자의 출력](api-gateway-lambda-authorizer-output.md) 섹션을 참조하세요.

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

## `TOKEN` 권한 부여자 Lambda 함수 예제
<a name="api-gateway-lambda-authorizer-token-lambda-function-create"></a>

다음 예제 코드는 클라이언트 제공 토큰 값이 `allow`이면 호출자가 메서드를 간접적으로 호출하도록 허용하는 `TOKEN` Lambda 권한 부여자 함수를 생성합니다. 토큰 값이 `deny`이면 호출자가 요청을 간접적으로 호출할 수 없습니다. 토큰 값이 `unauthorized` 또는 빈 문자열인 경우 권한 부여자 함수는 `401 UNAUTHORIZED` 응답을 반환합니다.

------
#### [ 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
```

------

이 예제에서는 API가 메서드 요청을 받을 때 API Gateway가 소스 토큰을 이 Lambda 권한 부여자 함수의 `event.authorizationToken` 속성에 전달합니다. Lambda 권한 부여자 함수는 토큰을 읽고 다음과 같이 동작합니다.
+ 토큰 값이 `allow`인 경우 권한 부여자 함수는 `200 OK` HTTP 응답 및 다음과 같은 IAM 정책을 반환하고 메서드 요청이 성공합니다.

------
#### [ JSON ]

****  

  ```
  {
    "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 정책을 반환하고 메서드 요청이 실패합니다.

------
#### [ JSON ]

****  

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

------
**참고**  
테스트 환경 밖에서는 API Gateway가 `403 Forbidden` HTTP 응답을 반환하고 메서드 요청이 실패합니다.
+ 토큰 값이 `unauthorized`이나 빈 문자열인 경우 권한 부여자 함수는 `401 Unauthorized` HTTP 응답을 반환하고 메서드 호출이 실패합니다.
+ 그 외 토큰의 경우 클라이언트는 `500 Invalid token` 응답을 수신하고, 메서드 호출은 실패합니다.

Lambda 권한 부여자 함수는 IAM 정책을 반환하는 것 외에 호출자의 보안 주체 ID도 반환해야 합니다. 선택적으로 통합 백엔드로 전달될 수 있는 추가 정보를 포함하는 `context` 객체를 반환할 수 있습니다. 자세한 내용은 [API Gateway Lambda 권한 부여자의 출력](api-gateway-lambda-authorizer-output.md) 섹션을 참조하세요.

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

## Lambda 권한 부여자 함수의 추가 예제
<a name="api-gateway-lambda-authorizer-lambda-function-create"></a>

다음 목록은 Lambda 권한 부여자 함수의 추가 예제를 보여줍니다. API를 생성한 계정과 동일한 계정이나 다른 계정에서 Lambda 함수를 생성할 수 있습니다.

이전 Lambda 함수 예제는 다른 AWS 서비스를 직접적으로 호출하지 않으므로 기본으로 제공되는 [AWSLambdaBasicExecutionRole](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)을 사용할 수 있습니다. Lambda 함수가 다른 AWS 서비스를 호출한다면 Lambda 함수에 IAM 실행 역할을 할당해야 합니다. 역할을 생성하려면 [AWS Lambda 실행 역할](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)의 지침을 따르세요.

**Lambda 권한 부여자 함수의 추가 예제**
+  예제 애플리케이션은 GitHub의 [Open Banking Brazil - Authorization Samples](https://github.com/aws-samples/openbanking-brazilian-auth-samples)를 참조하세요.
+  더 많은 Lambda 함수 예제는 GitHub에 있는 [ aws-apigateway-lambda-authorizer-blueprints](https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints)를 참조하세요.
+ Amazon Cognito 사용자 풀을 사용하여 사용자를 인증하고 Verified Permissions를 사용하여 정책 스토어를 기반으로 호출자에게 권한을 부여하는 Lambda 권한 부여자를 생성할 수 있습니다. 자세한 내용은 [Verified Permissions를 사용하여 자격 증명의 속성을 기반으로 액세스 제어](apigateway-lambda-authorizer-verified-permissions.md) 섹션을 참조하세요.
+ Lambda 콘솔은 Python 블루프린트를 제공합니다. **블루프린트 사용**을 선택하고 **api-gateway-authorizer-python** 블루프린트를 선택하여 이 블루프린트를 사용할 수 있습니다.

# API Gateway Lambda 권한 부여자 구성
<a name="configure-api-gateway-lambda-authorization"></a>

Lambda 함수를 생성한 후 Lambda 함수를 API의 권한 부여자로 구성합니다. 그런 다음 Lambda 권한 부여자를 간접적으로 호출하도록 메서드를 구성하여 호출자가 메서드를 간접적으로 호출할 수 있는지 확인합니다. API를 생성한 계정과 동일한 계정이나 다른 계정에서 Lambda 함수를 생성할 수 있습니다.

API Gateway 콘솔에 기본으로 제공되는 도구를 사용하거나 [Postman](https://www.postman.com/)을 사용하여 Lambda 권한 부여자를 테스트할 수 있습니다. Postman을 사용하여 Lambda 권한 부여 함수를 테스트하는 방법에 대한 지침은 [API Gateway Lambda 권한 부여자를 사용한 API 직접 호출](call-api-with-api-gateway-lambda-authorization.md) 섹션을 참조하세요.

## Lambda 권한 부여자 구성(콘솔)
<a name="configure-api-gateway-lambda-authorization-with-console"></a>

 다음 절차는 API Gateway REST API 콘솔에서 Lambda 권한 부여자를 생성하는 방법을 보여줍니다. 다른 Lambda 권한 부여자 유형에 대해 자세히 알아보려면 [Lambda 권한 부여자 유형 선택](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-choose) 섹션을 참조하세요.

------
#### [ REQUEST authorizer ]

**`REQUEST` Lambda 권한 부여자를 구성하려면**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. API를 선택한 다음 **권한 부여자**를 선택합니다.

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

1. **권한 부여자 이름**에 권한 부여자의 이름을 입력합니다.

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

1. **Lambda 함수** 함수에서 Lambda 권한 부여자 함수를 생성한 AWS 리전을 선택하고 함수 이름을 입력합니다.

1. API Gateway REST API 콘솔이 리소스 기반 정책을 설정하도록 **Lambda 호출 역할**을 비워 둡니다. 이 정책은 API Gateway에 Lambda 권한 부여자 함수를 간접적으로 호출할 권한을 부여합니다. API Gateway가 Lambda 권한 부여자 함수를 간접적으로 호출하도록 허용하는 IAM 역할의 이름을 입력할 수도 있습니다. 예시 역할은 [맡을 수 있는 IAM 역할 생성](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies) 섹션을 참조하세요.

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

1. **자격 증명 소스 유형**에서 파리미터 유형을 선택합니다. 지원되는 파라미터 유형은 `Header`, `Query string`, `Stage variable` 및 `Context`입니다. 자격 증명 소스를 더 추가하려면 **파라미터 추가**를 선택합니다.

1. 권한 부여자에 의해 생성된 권한 부여 정책을 캐싱하려면 **권한 부여 캐싱**을 설정해 둡니다. 정책 캐싱을 활성화한 경우 **TTL** 값을 수정할 수 있습니다. **TTL**을 0으로 설정하면 정책 캐싱이 비활성화됩니다.

   캐싱을 활성화하는 경우 권한 부여자가 API 전체의 모든 메서드에 적용 가능한 정책을 반환해야 합니다. 메서드별 정책을 적용하려면 컨텍스트 변수 `$context.path` 및 `$context.httpMethod`를 사용하세요.

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

------
#### [ TOKEN authorizer ]

**`TOKEN` Lambda 권한 부여자를 구성하려면**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. API를 선택한 다음 **권한 부여자**를 선택합니다.

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

1. **권한 부여자 이름**에 권한 부여자의 이름을 입력합니다.

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

1. **Lambda 함수** 함수에서 Lambda 권한 부여자 함수를 생성한 AWS 리전을 선택하고 함수 이름을 입력합니다.

1. API Gateway REST API 콘솔이 리소스 기반 정책을 설정하도록 **Lambda 호출 역할**을 비워 둡니다. 이 정책은 API Gateway에 Lambda 권한 부여자 함수를 간접적으로 호출할 권한을 부여합니다. API Gateway가 Lambda 권한 부여자 함수를 간접적으로 호출하도록 허용하는 IAM 역할의 이름을 입력할 수도 있습니다. 예시 역할은 [맡을 수 있는 IAM 역할 생성](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies) 섹션을 참조하세요.

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

1. **토큰 소스**에 인증 토큰이 포함된 헤더 이름을 입력합니다. 호출자는 권한 부여 토큰을 Lambda 권한 부여자에게 전송하기 위해 이 이름의 헤더를 포함해야 합니다.

1. (선택 사항) **토큰 검증**에 정규 표현식 문을 입력합니다. API Gateway는 이 표현식에 대해 입력 토큰의 초기 확인을 수행하고 확인이 성공할 경우 권한 부여자를 호출합니다.

1. 권한 부여자에 의해 생성된 권한 부여 정책을 캐싱하려면 **권한 부여 캐싱**을 설정해 둡니다. 정책 캐싱을 비활성화한 경우 **토큰 소스**에 지정된 헤더 이름이 캐시 키가 됩니다. 정책 캐싱을 활성화한 경우 **TTL** 값을 수정할 수 있습니다. **TTL**을 0으로 설정하면 정책 캐싱이 비활성화됩니다.

   캐싱을 활성화하는 경우 권한 부여자가 API 전체의 모든 메서드에 적용 가능한 정책을 반환해야 합니다. 메서드별 정책을 적용하려는 경우 **권한 부여자 캐싱**을 끌 수 있습니다.

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

------

Lambda 권한 부여자를 생성한 후 테스트할 수 있습니다. 다음 절차는 Lambda 권한 부여자를 테스트하는 방법을 보여줍니다.

------
#### [ REQUEST authorizer ]

**`REQUEST` Lambda 권한 부여자를 테스트하려면**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. 권한 부여자의 이름을 선택합니다.

1. **테스트 권한 부여자**에 자격 증명 소스의 값을 입력합니다.

   [`REQUEST` 권한 부여자 Lambda 함수 예제](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-request-lambda-function-create)를 사용하는 경우 다음과 같이 합니다.

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

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

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

   테스트 간접 호출을 위한 컨텍스트 변수는 수정할 수 없지만 Lambda 함수의 **API Gateway 권한 부여자** 테스트 이벤트 템플릿은 수정할 수 있습니다. 그런 다음 수정된 컨텍스트 변수를 사용하여 Lambda 권한 부여자 함수를 테스트할 수 있습니다. 자세한 내용은 AWS Lambda 개발자 안내서의 [콘솔에서 Lambda 함수 테스팅](https://docs.aws.amazon.com/lambda/latest/dg/testing-functions.html)을 참조하세요.**

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

------
#### [ TOKEN authorizer ]

**`TOKEN` Lambda 권한 부여자를 테스트하려면**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. 권한 부여자의 이름을 선택합니다.

1. **테스트 권한 부여자**에 토큰 값을 입력합니다.

   [`TOKEN` 권한 부여자 Lambda 함수 예제](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-token-lambda-function-create)를 사용하는 경우 다음과 같이 합니다.

   1. **authorizationToken**에 **allow**를 입력합니다.

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

    Lambda 권한 부여자가 테스트 환경에서 요청을 성공적으로 거부하면 테스트는 `200 OK` HTTP 응답으로 응답합니다. 그러나 테스트 환경 밖에서는 API Gateway가 `403 Forbidden` HTTP 응답을 반환하고 메서드 요청이 실패합니다.

------

## Lambda 권한 부여자 구성(AWS CLI)
<a name="configure-api-gateway-lambda-authorization-cli"></a>

다음 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) 명령은 AWS CLI를 사용하여 Lambda 권한 부여자를 생성하는 방법을 보여줍니다.

------
#### [ REQUEST authorizer ]

다음 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) 명령은 `REQUEST` 권한 부여자를 생성하고 `Authorizer` 헤더와 `accountId` 컨텍스트 변수를 자격 증명 소스로 사용합니다.

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Request_Custom_Authorizer' \
    --type REQUEST \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization,context.accountId' \
    --authorizer-result-ttl-in-seconds 300
```

------
#### [ TOKEN authorizer ]

다음 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) 명령은 `TOKEN` 권한 부여자를 생성하고 `Authorization` 헤더를 자격 증명 소스로 사용합니다.

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Token_Custom_Authorizer' \
    --type TOKEN \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization' \
    --authorizer-result-ttl-in-seconds 300
```

------

Lambda 권한 부여자를 생성한 후 테스트할 수 있습니다. 다음 [test-invoke-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/test-invoke-authorizer.html) 명령은 Lambda 권한 부여자를 테스트합니다.

```
aws apigateway test-invoke-authorizer --rest-api-id 1234123412 \
   --authorizer-id efg1234 \
   --headers Authorization='Value'
```

## Lambda 권한 부여자를 사용하도록 메서드 구성(콘솔)
<a name="configure-api-gateway-lambda-authorization-method-console"></a>

Lambda 권한 부여자를 구성한 후 API에 대한 메서드에 연결해야 합니다. 권한 부여자가 권한 부여 캐싱을 사용하는 경우 정책을 업데이트하여 추가 메서드에 대한 액세스를 제어해야 합니다.

**Lambda 권한 부여자를 사용하도록 API 메서드를 구성하려면**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. API를 선택합니다.

1. **리소스**를 선택한 다음 새 메서드를 선택하거나 기존 메서드를 선택합니다.

1. **메서드 요청** 탭의 **메서드 요청 설정**에서 **편집**을 선택합니다.

1. **권한 부여자**의 경우 드롭다운 메뉴에서 방금 생성한 Lambda 권한 부여자를 선택합니다.

1.  (선택 사항) 권한 부여 토큰을 백엔드로 전달하려면 **HTTP 요청 헤더**를 선택합니다. **헤더 추가**를 선택한 다음 인증 헤더의 이름을 추가합니다. **이름**에서, API에 대한 Lambda 권한 부여자를 생성할 때 지정한 **토큰 소스** 이름과 일치하는 헤더 이름을 입력합니다. `REQUEST` 권한 부여자에는 이 단계가 적용되지 않습니다.

1. **저장**을 선택합니다.

1. **Deploy API(API 배포)**를 선택하여 단계에 API를 배포합니다. 스테이지 변수를 사용하는 `REQUEST` 권한 부여자의 경우 **스테이지** 페이지가 열려 있는 동안 필요한 스테이지 변수를 지정하고 값을 지정해야 합니다.

## Lambda 권한 부여자를 사용하도록 메서드 구성(AWS CLI)
<a name="configure-api-gateway-lambda-authorization-method-cli"></a>

Lambda 권한 부여자를 구성한 후 API에 대한 메서드에 연결해야 합니다. 새 메서드를 생성하거나 패치 작업을 사용하여 권한 부여자를 기존 메서드에 연결할 수 있습니다. 권한 부여자가 권한 부여 캐싱을 사용하는 경우 정책을 업데이트하여 추가 메서드에 대한 액세스를 제어해야 합니다.

다음 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 명령은 Lambda 권한 부여자를 사용하는 새 메서드를 생성합니다.

```
aws apigateway put-method --rest-api-id 1234123412 \
  --resource-id a1b2c3 \
  --http-method PUT \
  --authorization-type CUSTOM \
  --authorizer-id efg1234
```

다음 [update-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-method.html) 명령은 Lambda 권한 부여자를 사용하도록 기존 메서드를 업데이트합니다.

```
aws apigateway update-method \
    --rest-api-id 1234123412 \
    --resource-id a1b2c3 \
    --http-method PUT \
    --patch-operations op="replace",path="/authorizationType",value="CUSTOM" op="replace",path="/authorizerId",value="efg1234"
```

# API Gateway Lambda 권한 부여자에 대한 입력
<a name="api-gateway-lambda-authorizer-input"></a>

다음 섹션에서는 API Gateway에서 Lambda 권한 부여자로 보내는 입력 형식을 설명합니다.

## `TOKEN` 입력 형식
<a name="w2aac15b9c23c25c19b5"></a>

 `TOKEN` 유형 Lambda 권한 부여자(이전에는 사용자 지정 권한 부여자라고 함)의 경우 API에 대해 권한 부여자를 구성할 때 사용자 지정 헤더를 **토큰 원본**으로 지정해야 합니다. API 클라이언트는 수신되는 요청에 있는 해당 헤더의 권한 부여 토큰을 전달해야 합니다. 메서드 요청을 수신하면 API Gateway는 사용자 지정 헤더로부터 토큰을 추출합니다. 그런 다음 토큰을 Lambda 함수 내 `authorizationToken` 객체의 `event` 속성으로 전달하고 메서드 ARN을 `methodArn` 속성으로 전달합니다.

```
{
    "type":"TOKEN",
    "authorizationToken":"{caller-supplied-token}",
    "methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}
```

 이 예제에서 `type` 속성은 권한 부여자 유형(`TOKEN` 권한 부여자)을 지정합니다. `{caller-supplied-token}`의 출처는 클라이언트 요청의 권한 부여 헤더이며 모든 문자열 값이 될 수 있습니다. `methodArn`은 수신 메서드 요청의 ARN이며 API Gateway에서 Lambda 권한 부여자 구성에 따라 채워집니다.

## `REQUEST` 입력 형식
<a name="w2aac15b9c23c25c19b7"></a>

`REQUEST` 유형의 Lambda 권한 부여자의 경우, API Gateway가 요청 파라미터를 `event` 객체의 일부로 Lambda 함수에 전달합니다. 이러한 요청 파라미터에는 헤더, 경로 파라미터, 쿼리 문자열 파라미터, 단계 변수 및 일부 요청 컨텍스트 변수가 포함됩니다. API 호출자는 경로 파라미터, 헤더 및 쿼리 문자열 파라미터를 설정할 수 있습니다. API 개발자는 API를 배포할 때 단계 변수를 설정해야 하며, API Gateway는 런타임 시 요청 컨텍스트를 제공합니다.

**참고**  
경로 파라미터는 Lambda 권한 부여자 함수에 요청 파라미터로 전달될 수 있지만, 자격 증명 원본으로 사용될 수는 없습니다.

 다음 예제는 프록시 통합을 포함하는 API 메서드(`REQUEST`)에 대한 `GET /request` 권한 부여자에 대한 입력입니다.

```
{
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "resource": "/request",
  "path": "/request",
  "httpMethod": "GET",
  "headers": {
    "X-AMZ-Date": "20170718T062915Z",
    "Accept": "*/*",
    "HeaderAuth1": "headerValue1",
    "CloudFront-Viewer-Country": "US",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "User-Agent": "..."
  },
  "queryStringParameters": {
    "QueryString1": "queryValue1"
  },
  "pathParameters": {},
  "stageVariables": {
    "StageVar1": "stageValue1"
  },
  "requestContext": {
    "path": "/request",
    "accountId": "123456789012",
    "resourceId": "05c7jb",
    "stage": "test",
    "requestId": "...",
    "identity": {
      "apiKey": "...",
      "sourceIp": "...",
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "resourcePath": "/request",
    "httpMethod": "GET",
    "apiId": "abcdef123"
  }
}
```

 `requestContext`는 키-값 페어의 맵이며 [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) 변수에 해당합니다. 결과는 API 종속적입니다.

 API Gateway는 새 키를 맵에 추가할 수 있습니다. Lambda 프록시 통합에서의 Lambda 함수에 대한 자세한 내용은 [프록시 통합에 대한 Lambda 함수의 입력 형식](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format) 단원을 참조하세요.

# API Gateway Lambda 권한 부여자의 출력
<a name="api-gateway-lambda-authorizer-output"></a>

Lambda 권한 부여자 함수의 출력은 사전과 같은 객체이며, 이 객체에는 보안 주체 ID(`principalId`)와 정책 설명 목록이 들어 있는 정책 문서(`policyDocument`)가 포함되어 있어야 합니다. 또한 키-값 페어를 포함하는 `context` 맵을 포함할 수 있습니다. API가 사용량 계획을 사용하는 경우([https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apiKeySource](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apiKeySource)가 `AUTHORIZER`로 설정됨), Lambda 권한 부여자 함수는 `usageIdentifierKey` 속성 값으로 사용량 계획의 API 키 중 하나를 반환해야 합니다.

다음은 이 출력의 예입니다.

------
#### [ JSON ]

****  

```
{
  "principalId": "yyyyyyyy", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "stringKey": "value",
    "numberKey": "1",
    "booleanKey": "true"
  },
  "usageIdentifierKey": "{api-key}"
}
```

------

 여기서 정책 설명은 API Gateway 실행 서비스에서 지정된 API 메서드(`Effect`)를 호출(`Action`)하도록 허용할지 거부할지(`Resource`) 여부를 지정합니다. 권한 부여자에 따라 여러 리소스에 대한 액세스를 제어해야 할 수 있습니다. 와일드카드(`*`)를 사용하여 리소스 유형(메서드)를 지정할 수 있습니다. API 호출에 대한 유효한 정책을 설정하는 방법은 [API Gateway에서 API 실행을 위한 IAM 정책의 설명 참조](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-calling-api-permissions) 단원을 참조하세요.

권한 부여가 활성화된 메서드 ARN의 경우(예: `arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]`) 최대 길이는 1,600바이트입니다. 경로 파라미터 값은 실행 시간에 값 크기가 결정되기 때문에 ARN 길이가 한도를 초과하게 될 가능성이 있습니다. 이런 일이 발생하면 API 클라이언트는 `414 Request URI too long` 응답을 받습니다.

뿐만 아니라 권한 부여자의 정책 설명 출력 내용과 마찬가지로 리소스 ARN은 현재 512자로 제한되어 있습니다. 이런 이유 때문에 요청 URI에서는 길이가 상당히 긴 JWT 토큰이 있는 URI를 사용해서는 안 됩니다. 그 대신에 요청 헤더에서 JWT 토큰을 안전하게 전달할 수도 있습니다.

 `principalId` 변수를 사용하여 매핑 템플릿에서 `$context.authorizer.principalId` 값에 액세스할 수 있습니다. 이 기능은 값을 백엔드에 전달하려는 경우에 유용합니다. 자세한 내용은 [데이터 변환용 컨텍스트 변수](api-gateway-mapping-template-reference.md#context-variable-reference) 단원을 참조하세요.

 각각 `stringKey`, `numberKey` 또는 `booleanKey`를 호출하여 매핑 템플릿에서 `"value"` 맵의 `"1"`, `"true"` 또는 `context` 값(예: `$context.authorizer.stringKey`, `$context.authorizer.numberKey` 또는 `$context.authorizer.booleanKey`)에 액세스할 수 있습니다. 반환되는 값은 모두 문자열화됩니다. JSON 객체 또는 어레이를 `context` 맵의 유효한 키 값으로 설정할 수 없습니다.

 `context` 맵을 사용하면 통합 요청 매핑 템플릿을 사용해 캐시된 자격 증명을 권한 부여자에서 백엔드로 반환할 수 있습니다. 그러면 캐시된 자격 증명을 사용해 모든 요청에 대해 보안 키에 액세스하고 권한 부여 토큰을 열 필요를 줄일 수 있으므로 백엔드가 개선된 사용자 경험을 제공할 수 있습니다.

 Lambda 프록시 통합의 경우 API Gateway가 `context` 객체를 입력 `event`의 일부로 Lambda 권한 부여자에서 백엔드 Lambda 함수로 직접 전달합니다. `context`를 호출하여 Lambda 함수에서 `$event.requestContext.authorizer.key` 키-값 페어를 검색할 수 있습니다.

`{api-key}`는 API 단계의 사용량 계획에서 API 키를 뜻합니다. 자세한 내용은 [API Gateway의 REST API 사용량 계획 및 API 키](api-gateway-api-usage-plans.md) 단원을 참조하세요.

 다음 예제는 Lambda 권한 부여자의 출력을 보여줍니다. 예제 출력에는 AWS 계정(`123456789012`)의 API(`ymy8tbxw7b`) `dev` 스테이지에 대해 `GET` 메서드에 대한 호출을 차단(`Deny`)하는 정책 설명이 포함되어 있습니다.

------
#### [ JSON ]

****  

```
{
  "principalId": "user",
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/dev/GET/"
      }
    ]
  }
}
```

------

# API Gateway Lambda 권한 부여자를 사용한 API 직접 호출
<a name="call-api-with-api-gateway-lambda-authorization"></a>

 Lambda 권한 부여자(이전에는 사용자 지정 권한 부여자라고 함)를 구성하고 API를 배포했으면 Lambda 권한 부여자가 활성화된 상태에서 API를 테스트해야 합니다. 이를 위해서는 REST 클라이언트(예: cURL 또는 [Postman](https://www.postman.com/))가 필요합니다. 다음 예제에서는 Postman을 사용합니다.

**참고**  
 권한 부여자 사용 메서드를 호출할 때 지정된 **토큰 확인 표현식**에 필요한 `TOKEN` 권한 부여자가 설정되어 있지 않거나 null이거나 무효화된 경우 API Gateway에서는 CloudWatch에 대한 호출을 기록하지 않습니다. 마찬가지로 API Gateway는 `REQUEST` 권한 부여자에 필요한 자격 증명 원본이 하나라도 설정되지 않았거나, null이거나, 비어 있을 경우 CloudWatch에 대한 호출을 기록하지 않습니다.

 다음에서는 Postman을 사용하여 Lambda `TOKEN` 권한 부여자로 API를 호출하거나 테스트하는 방법을 보여줍니다. 이 방법은 필요한 경로, 헤더 또는 쿼리 문자열 파라미터를 명시적으로 지정할 경우 Lambda `REQUEST` 권한 부여자를 사용해 API를 호출하는 데 적용할 수 있습니다.

**사용자 지정 `TOKEN` 권한 부여자를 사용해 API를 호출하려면**

1.  **Postman**을 열고 **GET** 메서드를 선택한 후 API의 **Invoke URL(URL 호출)**을 인접한 URL 필드에 붙여 넣습니다.

    Lambda 권한 부여 토큰 헤더를 추가하고 값을 `allow`로 설정합니다. **Send(전송)**를 선택합니다.  
![\[Lambda 권한 부여 허용 토큰을 사용하여 API 호출\]](http://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/images/custom-auth-call-api-with-allow-token.png)

    응답을 보면, API Gateway Lambda 권한 부여자가 **200 OK** 응답을 반환하고, 메서드와 통합된 HTTP 엔드포인트(http://httpbin.org/get)에 액세스할 수 있는 호출 권한을 부여함을 알 수 있습니다.

1.  Postman에 머물면서 Lambda 권한 부여 토큰 헤더 값을 `deny`로 변경합니다. **Send(전송)**를 선택합니다.  
![\[Lambda 권한 부여 거부 토큰을 사용하여 API 호출\]](http://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/images/custom-auth-call-api-with-deny-token.png)

   응답을 보면, API Gateway Lambda 권한 부여자가 **403 Forbidden** 응답을 반환하고, HTTP 엔드포인트에 액세스할 수 있는 호출 권한을 부여하지 않음을 알 수 있습니다.

1.  Postman에서 Lambda 권한 부여 토큰 헤더 값을 `unauthorized`로 변경하고 **전송**을 선택합니다.  
![\[Lambda 권한 부여 권한 없음 토큰을 사용하여 API 호출\]](http://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/images/custom-auth-call-api-with-unauthorized-token.png)

    응답을 보면, API Gateway가 **401 Unauthorized** 응답을 반환하고, HTTP 엔드포인트에 액세스할 수 있는 호출 권한을 부여하지 않음을 알 수 있습니다.

1.  이제 Lambda 권한 부여 토큰 헤더 값을 `fail`로 변경합니다. **Send(전송)**를 선택합니다.  
![\[Lambda 권한 부여 실패 토큰을 사용하여 API 호출\]](http://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/images/custom-auth-call-api-with-fail-token.png)

    응답을 보면, API Gateway가 **500 Internal Server Error** 응답을 반환하고, HTTP 엔드포인트에 액세스할 수 있는 호출 권한을 부여하지 않음을 알 수 있습니다.

# 교차 계정 API Gateway Lambda 권한 부여자 구성
<a name="apigateway-lambda-authorizer-cross-account-lambda-authorizer"></a>

이제는 다른 AWS Lambda 계정의 AWS 함수도 API 권한 부여자 함수로 사용할 수 있습니다. 각 계정은 Amazon API Gateway를 사용할 수 있는 모든 리전에 존재할 수 있습니다. Lambda 권한 부여자 함수는 OAuth 또는 SAML 같은 보유자 토큰 인증 전략을 사용할 수 있습니다. 따라서 여러 API Gateway API에 대해 Lambda 권한 부여자 함수를 중앙에서 손쉽게 관리 및 공유할 수 있습니다.

이 단원에서는 Amazon API Gateway 콘솔을 사용하여 교차 계정 Lambda 권한 부여자 함수를 구성하는 방법을 보여줍니다.

이 지침에서는 한 AWS 계정에서 API Gateway API를, 다른 계정에서는 Lambda 권한 부여자 함수를 이미 생성했다고 가정합니다.

## API Gateway 콘솔을 사용하여 교차 계정 Lambda 권한 부여자 구성
<a name="apigateway-cross-account-lambda-auth-configure-cross-account-authorizer"></a>

API를 포함하고 있는 계정에서 Amazon API Gateway 콘솔에 로그인하고 다음을 수행합니다.

1. API를 선택하고 기본 탐색 창에서 **권한 부여자**를 선택합니다.

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

1. **권한 부여자 이름**에 권한 부여자의 이름을 입력합니다.

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

1. **Lambda 함수**에서 두 번째 계정에서 생성한 Lambda 권한 부여자 함수의 정식 ARN을 입력합니다.
**참고**  
Lambda 콘솔 창의 오른쪽 위 모서리에서 함수의 ARN을 찾을 수 있습니다.

1. `aws lambda add-permission` 명령 문자열과 함께 경고가 표시됩니다. 이 정책은 권한 부여자 Lambda 함수를 호출할 API Gateway 권한을 부여합니다. 나중에 사용하기 위해 명령을 복사하여 저장합니다. 권한 부여자를 생성한 후 명령을 실행합니다.

1. **Lambda 이벤트 페이로드**에서 `TOKEN` 권한 부여자는 **토큰**을, `REQUEST` 권한 부여자는 **요청**을 선택합니다.

1. 이전 단계에서의 선택에 따라 다음 중 하나를 수행합니다.

   1.  **토큰** 옵션의 경우 다음을 수행합니다.
      + **토큰 소스**에 인증 토큰이 포함된 헤더 이름을 입력합니다. API 클라이언트는 권한 부여 토큰을 Lambda 권한 부여자에게 전송하려면 이 이름의 헤더를 포함해야 합니다.
      + 선택적으로 **토큰 검증**에 정규 표현식 문을 입력합니다. API Gateway는 이 표현식에 대해 입력 토큰의 초기 확인을 수행하고 확인이 성공할 경우 권한 부여자를 호출합니다. 이렇게 하면 API 호출을 줄일 수 있습니다.
      + 권한 부여자에 의해 생성된 권한 부여 정책을 캐싱하려면 **권한 부여 캐싱**을 설정해 둡니다. 정책 캐싱을 활성화한 경우 **TTL** 값을 수정할 수 있습니다. **TTL**을 0으로 설정하면 정책 캐싱이 비활성화됩니다. 정책 캐싱을 비활성화한 경우 **토큰 소스**에 지정된 헤더 이름이 캐시 키가 됩니다. 요청에서 이 헤더에 여러 값이 전달되면 모든 값이 순서가 유지된 상태로 캐시 키가 됩니다.
**참고**  
기본 **TTL** 값은 300초입니다. 최대 TTL 값은 3600초이며, 이 제한은 늘릴 수 없습니다.

   1. **요청** 옵션의 경우 다음을 수행합니다.
      + **자격 증명 소스 유형**에서 파리미터 유형을 선택합니다. 지원되는 파라미터 유형은 `Header`, `Query string`, `Stage variable` 및 `Context`입니다. 자격 증명 소스를 더 추가하려면 **파라미터 추가**를 선택합니다.
      + 권한 부여자에 의해 생성된 권한 부여 정책을 캐싱하려면 **권한 부여 캐싱**을 설정해 둡니다. 정책 캐싱을 활성화한 경우 **TTL** 값을 수정할 수 있습니다. **TTL**을 0으로 설정하면 정책 캐싱이 비활성화됩니다.

        API Gateway는 지정된 자격 증명 원본을 요청 권한 부여자 캐싱 키로 사용합니다. 캐싱을 활성화한 경우 API Gateway가 런타임 시 모든 지정된 자격 증명 원본이 존재하는 것을 성공적으로 확인한 경우에만 권한 부여자의 Lambda 함수를 호출합니다. 지정된 자격 증명 원본이 없거나, Null이거나, 비어 있을 경우 API Gateway가 권한 부여자 Lambda 함수를 직접적으로 호출하지 않고 `401 Unauthorized` 응답을 반환합니다.

        여러 개의 자격 증명 소스가 정의된 경우, 이들은 모두 권한 부여자의 캐시 키를 도출하는 데 사용됩니다. 캐시 키 부분을 변경하면 권한 부여자가 캐시된 정책 문서를 폐기하고 새로 생성합니다. 요청에서 여러 값이 있는 헤더가 전달되면 모든 값이 순서가 유지된 상태로 캐시 키의 일부가 됩니다.
      + 캐싱을 비활성화한 경우 자격 증명 소스를 지정할 필요가 없습니다.
**참고**  
 캐싱을 활성화하려면 권한 부여자가 API 전체의 모든 메서드에 적용 가능한 정책을 반환해야 합니다. 메서드별 정책을 적용하려는 경우 **권한 부여자 캐싱**을 해제할 수 있습니다.

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

1. 이전 단계에서 복사한 `aws lambda add-permission` 명령 문자열을 두 번째 계정에 대해 구성된 AWS CLI 창에 붙여 넣습니다. `AUTHORIZER_ID`를 권한 부여자의 ID로 바꿉니다. 이렇게 하면 첫 번째 계정이 두 번째 계정의 Lambda 권한 부여자 함수에 액세스할 수 있는 권한이 부여됩니다.

# Verified Permissions를 사용하여 자격 증명의 속성을 기반으로 액세스 제어
<a name="apigateway-lambda-authorizer-verified-permissions"></a>

Amazon Verified Permissions를 사용하여 API Gateway API에 대한 액세스를 제어합니다. Verified Permissions와 함께 API Gateway를 사용하는 경우 Verified Permissions가 세분화된 권한 부여 결정을 사용하여 API에 대한 액세스를 제어하는 Lambda 권한 부여자를 생성합니다. Verified Permissions는 Cedar 정책 언어를 사용해 애플리케이션 사용자에 대한 세분화된 권한을 정의하여 정책 스토어 스키마 및 정책을 기반으로 호출자에게 권한을 부여합니다. 자세한 내용은 *Amazon Verified Permissions 사용 설명서*의 [연결된 API 및 ID 공급자를 사용하여 정책 저장소 생성](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/getting-started-api-policy-store.html)을 참조합니다.

Verified Permissions는 자격 증명 소스로서 Amazon Cognto 사용자 풀 또는 OpenID Connect(OIDC) ID 제공업체를 지원합니다. Verified Permissions는 보안 주체가 이전에 식별되고 인증된 것으로 가정합니다. Verified Permissions는 리전 및 엣지 최적화 REST API에만 지원됩니다.

## Verified Permissions를 사용하여 Lambda 권한 부여자 생성
<a name="apigateway-lambda-authorizer-verified-permissions-attach"></a>

Verified Permissions는 Lambda 권한 부여자를 생성하여 보안 주체가 API에서 작업을 수행할 수 있는지 여부를 결정합니다. Verified Permissions가 권한 부여 작업을 수행하는 데 사용할 Cedar 정책을 생성합니다.

다음은 API의 `GET /users` 리소스에 있는 `developer` 그룹에 대해 Amazon Cognito 사용자 풀 `us-east-1_ABC1234`를 기반으로 API를 간접적으로 호출할 수 있도록 액세스를 허용하는 Cedar 정책의 예시입니다. Verified Permissions는 발신자 ID에 대한 보유자 토큰을 구문 분석하여 그룹 멤버십을 결정합니다.

```
permit(
  principal in MyAPI::UserGroup::"us-east-1_ABC1234|developer",
  action in [ MyAPI::Action::"get /users" ],
  resource
  );
```

선택적으로 Verified Permissions에서 API의 메서드에 권한 부여자를 연결할 수 있습니다. API의 프로덕션 스테이지에서는 Verified Permissions의 권한 부여자 연결을 허용하지 않는 것이 좋습니다.

다음 목록은 Lambda 권한 부여자를 API 메서드의 메서드 요청에 연결하거나 연결하지 않도록 Verified Permissions를 구성하는 방법을 보여줍니다.

**권한 부여자 연결(AWS Management Console)**  
Verified Permissions 콘솔에서 **정책 스토어 생성**을 선택할 때 **앱 통합 배포** 페이지에서 **지금**을 선택합니다.

**권한 부여자 연결 안 함(AWS Management Console)**  
Verified Permissions 콘솔에서 **정책 스토어 생성**을 선택할 때 **앱 통합 배포** 페이지에서 **나중에**를 선택합니다.  
Verified Permissions는 여전히 Lambda 권한 부여자를 생성합니다. Lambda 권한 부여자는 `AVPAuthorizerLambda-`로 시작합니다. 메서드에 권한 부여자를 연결하는 방법에 대한 자세한 지침은 [Lambda 권한 부여자를 사용하도록 메서드 구성(콘솔)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-console) 섹션을 참조하세요.

**권한 부여자 연결(CloudFormation)**  
Verified Permissions에서 생성된 CloudFormation 템플릿의 `Conditions` 섹션에서 `"Ref": "shouldAttachAuthorizer"`를 `true`로 설정합니다.

**권한 부여자 연결 안 함(CloudFormation)**  
Verified Permissions에서 생성된 CloudFormation 템플릿의 `Conditions` 섹션에서 `"Ref": "shouldAttachAuthorizer"`를 `false`로 설정합니다.  
Verified Permissions는 여전히 Lambda 권한 부여자를 생성합니다. Lambda 권한 부여자는 `AVPAuthorizerLambda-`로 시작합니다. 메서드에 권한 부여자를 연결하는 방법에 대한 자세한 지침은 [Lambda 권한 부여자를 사용하도록 메서드 구성(AWS CLI)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-cli) 섹션을 참조하세요.

## Verified Permissions를 사용하여 Lambda 권한 부여자 직접 호출
<a name="apigateway-lambda-authorizer-verified-permissions-call"></a>

`Authorization` 헤더에 자격 증명 또는 액세스 토큰을 제공하여 Lambda 권한 부여자를 직접적으로 호출할 수 있습니다. 자세한 내용은 [API Gateway Lambda 권한 부여자를 사용한 API 직접 호출](call-api-with-api-gateway-lambda-authorization.md) 섹션을 참조하세요.

API Gateway는 Lambda 권한 부여자가 반환하는 정책을 120초 동안 캐싱합니다. API Gateway 콘솔에서 또는 AWS CLI를 사용하여 TTL을 수정할 수 있습니다.