

# 使用 API Gateway Lambda 授权方
<a name="apigateway-use-lambda-authorizer"></a>

使用 *Lambda 授权方*（以前称为*自定义授权方*）控制对 API 的访问。当客户端提出对 API 方法的请求时，API Gateway 会调用 Lambda 授权方。Lambda 授权方将调用方的身份作为输入，并返回 IAM 策略作为输出。

使用 Lambda 授权方实施自定义授权方案。该方案可以使用请求参数来确定调用方的身份或使用持有者令牌身份验证策略（例如 OAuth 或 SAML）。在 API Gateway REST API 控制台中、使用 AWS CLI 或 AWS SDK 创建 Lambda 授权方。

## Lambda 授权方授权工作流
<a name="api-gateway-lambda-authorizer-flow"></a>

下图展示了 Lambda 授权方的授权工作流。

![\[API Gateway Lambda 授权工作流\]](http://docs.aws.amazon.com/zh_cn/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 将返回 `401 Unauthorized` HTTP 响应，而不调用 Lambda 授权方函数。如果定义了多个身份来源，它们都将用于派生授权方的缓存键并保持相应顺序。您可以使用多个身份来源定义精细缓存键。  
如果您更改缓存键的任意部分并重新部署 API，授权方将丢弃缓存策略文档并生成新的文档。  
如果您为 `REQUEST` 授权方关闭授权缓存，API Gateway 会直接将请求传递给 Lambda 函数。

**基于令牌的 Lambda 授权方（`TOKEN` 授权方）**  
`TOKEN` 授权方接收持有者令牌（例如 JSON Web 令牌（JWT）或 OAuth 令牌）中的调用方身份。  
如果您为 `TOKEN` 授权方开启授权缓存，令牌来源中指定的标头名称将成为缓存键。  
此外，您还可以使用令牌验证来输入正则表达式语句。API Gateway 将针对此表达式执行输入令牌的初始验证并在成功验证后调用 Lambda 授权方函数。这有助于减少对您的 API 的调用。  
仅 `TOKEN` 授权方支持 `IdentityValidationExpression` 属性。有关更多信息，请参阅 [x-amazon-apigateway-authorizer 对象](api-gateway-swagger-extensions-authorizer.md)。

**注意**  
建议您使用 `REQUEST` 授权方来控制对 API 的访问。使用 `REQUEST` 授权方时，您可以基于多个身份来源控制对 API 的访问，而使用 `TOKEN` 授权方时则基于单一身份来源。此外，您还可以使用 `REQUEST` 授权方的多个身份来源分离缓存键。

## `REQUEST` 授权方 Lambda 函数示例
<a name="api-gateway-lambda-authorizer-request-lambda-function-create"></a>

以下代码示例创建一个 Lambda 授权方函数，如果客户端提供的 `HeaderAuth1` 标头、`QueryString1` 查询参数和 `StageVar1` 阶段变量都分别与 `headerValue1`、`queryValue1` 和 `stageValue1` 的指定值相匹配，该函数将允许调用请求。

------
#### [ 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 响应并且方法请求将失败。

除了返回 IAM 策略之外，Lambda 授权方函数还必须返回调用方的委托人标识符。它还可以选择返回一个 `context` 对象，其中包含可传入集成后端的其他信息。有关更多信息，请参阅 [来自 API Gateway Lambda 授权方的输出](api-gateway-lambda-authorizer-output.md)。

在生产代码中，您可能需要先对用户进行身份验证，然后才能授予授权。您可以通过调用身份验证提供程序，在 Lambda 函数中添加身份验证逻辑，如该提供程序的文档中的指示。

## `TOKEN` 授权方 Lambda 函数示例
<a name="api-gateway-lambda-authorizer-token-lambda-function-create"></a>

以下代码示例创建一个 `TOKEN` Lambda 授权方函数，如果客户端提供的令牌值为 `allow`，该函数将允许调用方调用方法。如果令牌值为 `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 将源令牌传递到 `event.authorizationToken` 属性中的此 Lambda 授权方函数。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` 响应并且方法调用失败。

除了返回 IAM 策略之外，Lambda 授权方函数还必须返回调用方的委托人标识符。它还可以选择返回一个 `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 函数示例，您可以使用内置 [AWSLambdaBasicExecutionRole](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)，因为这些函数不会调用其他 AWS 服务。如果您的 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)。
+ 您可以创建 Lambda 授权方，该授权方使用 Amazon Cognito 用户池对用户进行身份验证，并使用 Verified Permissions 根据策略存储对调用方进行授权。有关更多信息，请参阅 [使用 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. 通过以下网址登录到 API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择一个 API，然后选择**授权方**。

1. 选择**创建授权方**。

1. 对于**授权方名称**，输入授权方名称。

1. 对于**授权方类型**，选择 **Lambda**。

1. 对于 **Lambda 函数**，选择您在其中创建 Lambda 授权方函数的 AWS 区域，然后输入函数名称。

1. 将 **Lambda 调用角色**留空，以允许 API Gateway REST API 控制台设置基于资源的策略。此策略授予 API Gateway 调用 Lambda 授权方函数的权限。您还可以选择输入 IAM 角色的名称，以允许 API Gateway 调用 Lambda 授权方函数。有关角色示例，请参阅[创建一个可代入的 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** 设置为零将禁用策略缓存。

   如果启用缓存，授权方必须返回适用于 API 中所有方法的策略。要强制执行特定于方法的策略，请使用上下文变量 `$context.path` 和 `$context.httpMethod`。

1. 选择**创建授权方**。

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

**配置 `TOKEN` Lambda 授权方**

1. 通过以下网址登录到 API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择一个 API，然后选择**授权方**。

1. 选择**创建授权方**。

1. 对于**授权方名称**，输入授权方名称。

1. 对于**授权方类型**，选择 **Lambda**。

1. 对于 **Lambda 函数**，选择您在其中创建 Lambda 授权方函数的 AWS 区域，然后输入函数名称。

1. 将 **Lambda 调用角色**留空，以允许 API Gateway REST API 控制台设置基于资源的策略。此策略授予 API Gateway 调用 Lambda 授权方函数的权限。您还可以选择输入 IAM 角色的名称，以允许 API Gateway 调用 Lambda 授权方函数。有关角色示例，请参阅[创建一个可代入的 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** 设置为零将禁用策略缓存。

   如果启用缓存，授权方必须返回适用于 API 中所有方法的策略。要强制执行特定于方法的策略，您可以关闭**授权缓存**。

1. 选择**创建授权方**。

------

创建 Lambda 授权方后，您可以对其进行测试。以下过程介绍如何测试 Lambda 授权方。

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

**测试 `REQUEST` Lambda 授权方**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

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. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

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 方法。如果授权方使用授权缓存，请务必更新策略以控制其它方法的访问权限。

**配置 API 方法以使用 Lambda 授权方**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择 API。

1. 选择**资源**，然后选择一种新方法或选择现有方法。

1. 在**方法请求**选项卡上的**方法请求设置**下，选择**编辑**。

1. 对于**授权方**，从下拉菜单中选择您刚刚创建的 Lambda 授权方。

1.  （可选）如果您希望将授权令牌传递到后端，请选择 **HTTP 请求标头**。选择**添加标头**，然后添加授权标头的名称。在**名称**中，输入标头名称，该名称必须与您在为 API 创建 Lambda 授权方时指定的**令牌来源**名称相匹配。此步骤不适用于 `REQUEST` 授权方。

1. 选择**保存**。

1. 选择**部署 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 授权方函数的输出是类似于目录的对象，其中必须包含委托人标识符 (`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 授权方函数必须返回使用计划的 API 密钥之一作为 `usageIdentifierKey` 属性值。

下面显示了一个此类输出的示例。

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

------

 在此示例中，策略语句指定是允许还是拒绝 (`Effect`) API Gateway 执行服务调用 (`Action`) 指定的 API 方法 (`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}]]`，最大长度为 1600 字节。路径参数值（其大小在运行时确定）可能导致 ARN 长度超过限制。出现这种情况是时，API 客户端将收到 `414 Request URI too long` 响应。

此外，如授权方的策略声明中所示，资源 ARN 当前长度限制为 512 个字符。因此，您不能在请求 URI 中将 URI 与具有很大长度的 JWT 令牌一起使用。而是可以安全地在请求标头中传递 JWT 令牌。

 您可以使用 `$context.authorizer.principalId` 变量访问映射模板中的 `principalId` 值。如果您想要将该值传递到后端，这会非常有用。有关更多信息，请参阅 [数据转换的上下文变量](api-gateway-mapping-template-reference.md#context-variable-reference)。

 您可以通过分别调用 `$context.authorizer.stringKey`、`$context.authorizer.numberKey` 或 `$context.authorizer.booleanKey` 来访问映射模板中 `context` 映射的 `stringKey`、`numberKey` 或 `booleanKey` 值（如 `"value"`、`"1"` 或 `"true"`）。返回的值都是字符串化的。请注意，您不能在 `context` 映射中将 JSON 对象或数组设置为任何键的有效值。

 您可以使用 `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 授权方的示例输出。此示例输出包含一个策略语句，用于阻止 (`Deny`) 在 `dev` 阶段调用AWS账户 (`123456789012`) API (`ymy8tbxw7b`) 的 `GET` 方法。

------
#### [ 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 中。同样，如果 `REQUEST` 授权方所需的任何身份来源未设置、为 null 或为空，则 API Gateway 不会将该调用记录到 CloudWatch 中。

 在以下示例中，我们将说明如何在 Lambda `TOKEN` 授权方的情况下使用 Postman 调用或测试 API。如果您显式指定必需的路径、标头或查询字符串参数，则可应用此方法以使用 Lambda `REQUEST` 授权方调用 API。

**使用自定义 `TOKEN` 授权方调用 API**

1.  打开 **Postman**，选择 **GET** 方法，并将 API 的**调用 URL** 粘贴到相邻的 URL 字段中。

    添加 Lambda 授权令牌标头，并将值设置为 `allow`。选择**发送**。  
![\[使用 Lambda 授权允许令牌调用 API\]](http://docs.aws.amazon.com/zh_cn/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`。选择**发送**。  
![\[使用 Lambda 授权拒绝令牌调用 API\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/custom-auth-call-api-with-deny-token.png)

   响应显示，API Gateway Lambda 授权方返回了 **403 禁止访问**响应，而未授权调用访问 HTTP 端点。

1.  在 Postman 中，将 Lambda 授权令牌标头值更改为 `unauthorized`，并选择**发送**。  
![\[使用 Lambda 授权未授权令牌调用 API\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/custom-auth-call-api-with-unauthorized-token.png)

    响应显示，API Gateway 返回了 **401 未授权**响应，而未授权调用访问 HTTP 端点。

1.  现在，将 Lambda 授权令牌标头值更改为 `fail`。选择**发送**。  
![\[使用 Lambda 授权失败令牌调用 API\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/custom-auth-call-api-with-fail-token.png)

    响应显示，API Gateway 返回了 **500 内部服务器错误**响应，而未授权调用访问 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` 命令字符串。此策略授予 API Gateway 调用授权方 Lambda 函数的权限。复制命令并保存，以供稍后使用。您可在创建授权方后运行该命令。

1. 对于 **Lambda 事件有效载荷**，请选择**令牌**（对于 `TOKEN` 授权方）或**请求**（对于 `REQUEST` 授权方）。

1. 根据上一步的选择，执行下列操作之一：

   1.  对于**令牌**选项，执行下列操作：
      + 对于**令牌来源**，输入包含授权令牌的标头名称。API 客户端必须包括此标头名称才能将授权令牌发送到 Lambda 授权方。
      + 或者，对于**令牌验证**，输入正则表达式语句。API Gateway 将针对此表达式执行对输入令牌的初始验证并在成功验证后调用授权方。这有助于减少对您 API 的调用。
      + 要缓存授权方生成的授权策略，请将**授权缓存**保持开启状态。在启用策略缓存后，您可选择修改 **TTL** 值。将 **TTL** 设置为零将禁用策略缓存。在启用策略缓存后，**令牌来源**中指定的标头名称将成为缓存键。如果在请求中将多个值传递到此标头，则所有值都将成为缓存键，并保留顺序。
**注意**  
默认 **TTL** 值为 300 秒。最大值为 3600 秒；目前不能提高此限制。

   1. 对于**请求**选项，执行以下操作：
      + 在**身份源类型**中，选择一个参数类型。支持的参数类型为 `Header`、`Query string`、`Stage variable` 和 `Context`。要添加更多身份来源，请选择**添加参数**。
      + 要缓存授权方生成的授权策略，请将**授权缓存**保持开启状态。在启用策略缓存后，您可选择修改 **TTL** 值。将 **TTL** 设置为零将禁用策略缓存。

        API Gateway 将使用指定的身份来源作为请求授权方缓存键。在启用缓存后，API Gateway 将仅在成功确认所有指定的身份来源在运行时存在后才调用授权方的 Lambda 函数。如果指定的身份来源缺失、为 null 或为空，则 API Gateway 将返回 `401 Unauthorized` 响应，而不调用授权方 Lambda 函数。

        如果定义了多个身份来源，则它们都将用于派生授权方的缓存键。更改缓存键的任意部分将导致授权方丢弃缓存的策略文档并生成新的文档。如果在请求中传递了具有多个值的标头，则所有值都将成为缓存键的一部分，并保留顺序。
      + 在关闭缓存后，无需指定身份来源。
**注意**  
 要启用缓存，授权方必须返回适用于 API 中所有方法的策略。要强制执行特定于方法的策略，您可以关闭**授权缓存**。

1. 选择**创建授权方**。

1. 将您在上一步中复制的 `aws lambda add-permission` 命令字符串粘贴到为第二个账户配置的 AWS CLI 窗口中。使用您的授权方 ID 替换 `AUTHORIZER_ID`。这将向您的第一个账户授予对第二个账户的 Lambda 授权方函数的访问权限。

# 使用 Verified Permissions 根据身份的属性控制访问
<a name="apigateway-lambda-authorizer-verified-permissions"></a>

使用 Amazon Verified Permissions 控制对 API Gateway API 的访问。在将 API Gateway 与 Verified Permissions 结合使用时，Verified Permissions 会创建一个 Lambda 授权方，该授权者使用精细的授权决策来控制对 API 的访问。Verified Permissions 使用 Cedar 策略语言根据策略存储架构和策略来向调用方授权，以便为应用程序用户定义精细权限。有关更多信息，请参阅《Amazon Verified Permissions 用户指南》**中的 [Create a policy store with a connected API and identity provider](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/getting-started-api-policy-store.html)。

Verified Permissions 支持将 Amazon Cognito 用户池或 OpenID Connect（OIDC）身份提供商作为身份源。Verified Permissions 假设主体之前已被识别并经过身份验证。仅区域和边缘优化的 REST API 支持 Verified Permissions。

## 使用 Verified Permissions 创建 Lambda 授权方
<a name="apigateway-lambda-authorizer-verified-permissions-attach"></a>

Verified Permissions 会创建 Lambda 授权方以确定是否允许主体对 API 执行操作。您创建 Verified Permissions 用来执行其授权任务的 Cedar 策略。

以下是一个示例 Cedar 策略，该策略允许访问以调用基于 Amazon Cognito 用户池（即 API 的 `GET /users` 资源上的 `developer` 组的 `us-east-1_ABC1234`）的 API。Verified Permissions 通过解析调用方身份的持有者令牌来确定组成员资格。

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

（可选）Verified Permissions 可以将授权方附加到 API 的方法。在 API 的生产阶段，建议您禁止 Verified Permissions 为您附加授权方。

以下列表说明如何将 Verified Permissions 配置为附加或不附加到 API 方法的方法请求。

**为您附加授权方（AWS 管理控制台）**  
在 Verified Permissions 控制台中选择**创建策略存储**时，在**部署应用程序集成**页面上，选择**立即**。

**不要为您附加授权方（AWS 管理控制台）**  
在 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。