本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
概览
验证 API 密钥政策允许您在运行时对 API 密钥强制执行验证,仅允许拥有已批准 API 密钥的应用访问您的 API。此政策可确保 API 密钥有效、未被撤消,并且已获批准使用与 API 产品关联的特定资源。
此政策是一项可扩展政策,使用此政策可能会影响费用或使用情况,具体取决于您的 Apigee 许可。如需了解政策类型和使用情况影响,请参阅政策类型。
如需查看展示如何构建使用验证 API 密钥政策的 API 代理的教程,请参阅通过要求 API 密钥来保护 API。
示例
查询参数中的密钥
<VerifyAPIKey name="APIKeyVerifier"> <APIKey ref="request.queryparam.apikey" /> </VerifyAPIKey>
在此示例中,政策要求在名为 request.queryparam.apikey
的流变量中找到 API 密钥。变量 request.queryparam.{name}
是一个标准 Apigee 流变量,其中填充在客户端请求中传递的查询参数的值。
以下 curl
命令会在查询参数中传递 API 密钥:
curl http://myorg-test.apigee.net/mocktarget?apikey=IEYRtW2cb7A5Gs54A1wKElECBL65GVls
标头中的密钥
<VerifyAPIKey name="APIKeyVerifier"> <APIKey ref="request.header.x-apikey" /> </VerifyAPIKey>
在此示例中,政策要求在名为 request.header.x-apikey
的流变量中找到 API 密钥。变量 request.header.{name}
是一个标准 Apigee 流变量,其中填充在客户端请求中传递的标题的值。
以下 cURL 展示了如何在标头中传递 API 密钥:
curl "http://myorg-test.apigee.net/mocktarget" -H "x-apikey:IEYRtW2cb7A5Gs54A1wKElECBL65GVls"
变量中的密钥
<VerifyAPIKey name="APIKeyVerifier"> <APIKey ref="requestAPIKey.key"/> </VerifyAPIKey>
该政策可以引用任何包含密钥的变量。此示例中的政策从名为 requestAPIKey.key 的变量中提取 API 密钥。
该变量的填充方式由您决定。例如,您可以使用提取变量政策从名为 requestAPIKey.key 的查询参数填充 requestAPIKey.key,如下所示:
<ExtractVariables async="false" continueOnError="false" enabled="true" name="SetAPIKeyVar"> <Source>request</Source> <QueryParam name="myKey"> <Pattern ignoreCase="true">{key}</Pattern> </QueryParam> <VariablePrefix>requestAPIKey</VariablePrefix> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </ExtractVariables>
访问政策流变量
<AssignMessage async="false" continueOnError="false" enabled="true" name="accessverifyvars"> <AssignVariable> <Name>devFirstName</Name> <Ref>verifyapikey.verify-api-key.developer.firstName</Ref> <Value>ErrorOnCopy</Value> </AssignVariable> <AssignVariable> <Name>devLastName</Name> <Ref>verifyapikey.verify-api-key.developer.lastName</Ref> <Value>ErrorOnCopy</Value> </AssignVariable> <AssignVariable> <Name>devEmail</Name> <Ref>verifyapikey.verify-api-key.developer.email</Ref> <Value>ErrorOnCopy</Value> </AssignVariable> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="request"/> </AssignMessage>
针对有效的 API 密钥执行验证 API 密钥政策时,Apigee 会自动填充一组流变量。您可以使用这些变量访问应用名称、应用 ID 等信息,以及有关注册应用的开发者或公司的信息。在上面的示例中,验证 API 密钥执行后,您可使用分配消息政策访问开发者的名字、姓氏和电子邮件地址。
这些变量均具有以下前缀:
verifyapikey.{policy_name}
在此示例中,验证 API 密钥政策名称为“verify-api-key”。因此,您可以通过访问变量 verifyapikey.verify-api-key.developer.firstName.
来引用发出请求的开发者的名字
了解 Apigee
关于验证 API 密钥政策
当开发者在 Apigee 上注册应用时,Apigee 会自动生成使用方密钥和密钥令牌对。您可以在 Apigee 界面中查看应用的使用方密钥和密钥令牌对,也可以通过 Apigee API 访问它们。
在应用注册时,开发者会选择一个或多个要与应用关联的 API 产品,其中 API 产品是可通过 API 代理访问的资源集合。然后,开发者会将 API 密钥(使用方密钥)作为每个请求的一部分传递到与应用关联的 API 产品中的某个 API 中。如需了解详情,请参阅发布概览。
API 密钥可以用作身份验证令牌,也可以用于获取 OAuth 访问令牌。在 OAuth 中,API 密钥称为“客户端 ID”。这些名称可以互换使用。如需了解详情,请参阅 OAuth 首页。
执行验证 API 密钥政策时,Apigee 会自动填充一组流变量。如需了解详情,请参阅下文的流变量。
元素参考
您可以在此政策中配置以下元素和属性:
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key-1"> <DisplayName>Custom label used in UI</DisplayName> <APIKey ref="variable_containing_api_key"/> <CacheExpiryInSeconds ref="request.queryparam.cache_expiry">Default value</CacheExpiryInSeconds/> </VerifyAPIKey>
<VerifyAPIKey> 属性
以下示例展示了 <VerifyAPIKey>
标记的属性:
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key-1">
下表介绍了所有政策父元素通用的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
name |
政策的内部名称。 (可选)使用 |
不适用 | 必填 |
continueOnError |
设置为 设置为 |
false | 可选 |
enabled |
设置为 设为 |
true | 可选 |
async |
此特性已弃用。 |
false | 已弃用 |
<DisplayName> 元素
除了用于 name
属性之外,还可以用于在管理界面代理编辑器中给政策添加不同的自然语言名称标签。
<DisplayName>Policy Display Name</DisplayName>
默认值 |
不适用 如果省略此元素,则会使用政策的 |
---|---|
状态 | 可选 |
类型 | 字符串 |
<APIKey> 元素
此元素指定包含 API 密钥的流变量。通常,客户端会在查询参数、HTTP 标头或表单参数中发送 API 密钥。例如,如果在名为 x-apikey
的标头中发送密钥,则可在以下变量中找到此密钥:request.header.x-apikey
默认 | NA |
---|---|
状态 | 必填 |
类型 | 字符串 |
属性
下表说明 <APIKey>
元素的属性
属性 | 说明 | 默认 | 状态 |
---|---|---|---|
ref |
对包含 API 密钥的变量的引用。每个政策只能有一个位置。 |
不适用 | 必填 |
示例
在这些示例中,密钥会传入参数和名为 x-apikey
的标头。
作为查询参数:
<VerifyAPIKey name="APIKeyVerifier"> <APIKey ref="request.queryparam.x-apikey"/> </VerifyAPIKey>
作为 HTTP 标头:
<VerifyAPIKey name="APIKeyVerifier"> <APIKey ref="request.header.x-apikey"/> </VerifyAPIKey>
作为 HTTP 表单参数:
<VerifyAPIKey name="APIKeyVerifier"> <APIKey ref="request.formparam.x-apikey"/> </VerifyAPIKey>
<CacheExpiryInSeconds> 元素
此元素会对缓存强制执行 TTL,从而自定义缓存访问令牌到期的时间段。 支持的范围介于 1 到 180 秒之间。您可以提供流变量和默认变量。 如果提供,则流变量值优先于指定的默认值。
<CacheExpiryInSeconds ref="request.queryparam.cache_expiry">Value 1</CacheExpiryInSeconds>
默认 | 不适用
如果您省略此元素,则缓存访问令牌的默认有效期为 180 秒。 |
---|---|
状态 | 可选 |
类型 | 整数 |
有效值 | 任何非零正整数。指定到期时间(以秒为单位)。 |
属性
下表说明 <CacheExpiryInSeconds>
元素的属性
属性 | 说明 | 默认 | 状态 |
---|---|---|---|
ref |
对包含缓存到期时间值(以秒为单位)的流变量的引用。 如果提供,则流变量值优先于指定的默认值。 |
不适用 | 可选 |
架构
流变量
当对有效的 API 密钥强制执行验证 API 密钥政策时,Apigee 会填充一组流变量。这些变量可用于流中稍后执行的策略或代码,通常用于根据 API 密钥的属性(如应用名称、用于授权密钥的 API 产品或 API 密钥的自定义属性)执行自定义处理。
政策可填充几种不同类型的流变量,包括:
- 常规
- 应用
- 开发者
- Google Analytics
- 获利
每种类型的流变量具有不同的前缀。所有变量均为标量,但明确指定为数组的变量除外。
常规流变量
下表列出由验证 API 密钥政策填充的常规流变量。这些变量均具有以下前缀:
verifyapikey.{policy_name}
例如:verifyapikey.{policy_name}.client_id
可用变量包括:
变量 | 说明 |
---|---|
client_id |
发出请求的应用提供的使用方密钥(也称为 API 密钥或应用密钥)。 |
client_secret |
与使用方密钥关联的使用方密钥。 |
redirection_uris |
请求中的任何重定向 URI。 |
developer.app.id |
发出请求的开发者或 AppGroup 应用的 ID。 |
developer.app.name |
发出请求的开发者或 AppGroup 应用的应用名称。 |
developer.id |
开发者或注册为发出请求的应用的所有者的 AppGroup 的 ID。 |
developer.{custom_attrib_name} |
派生自应用密钥配置文件的所有自定义属性。 |
DisplayName |
政策的 <DisplayName> 属性的值。 |
failed |
当 API 密钥验证失败时设置为“true”。 |
{custom_app_attrib} |
派生自应用配置文件的所有自定义属性。指定自定义属性的名称。 |
apiproduct.name* |
用于验证请求的 API 产品的名称。 |
apiproduct.{custom_attrib_name}* |
派生自 API 产品配置文件的任何自定义属性。 |
apiproduct.developer.quota.limit* |
在 API 产品上设置的配额限制(如有)。 |
apiproduct.developer.quota.interval* |
在 API 产品上设置的配额间隔(如有)。 |
apiproduct.developer.quota.timeunit* |
在 API 产品上设置的配额时间单位(如有)。 |
* 如果 API 产品配置了有效的环境、代理和资源(派生自 proxy.pathsuffix ),则系统会自动填充 API 产品变量。如需了解如何设置 API 产品,请参阅管理 API 产品。 |
应用流变量
政策将填充以下包含应用相关信息的流变量。这些变量均具有以下前缀:
verifyapikey.{policy_name}.app
。
例如:
verifyapikey.{policy_name}.app.name
可用变量包括:
变量 | 说明 |
---|---|
name |
应用的名称。 |
id |
应用的 ID。 |
accessType |
Apigee 未使用。 |
callbackUrl |
应用的回调网址。通常仅用于 OAuth。 |
DisplayName |
应用的显示名称。 |
status |
应用状态,例如“已批准”或“已撤消”。 |
apiproducts |
包含与应用关联的 API 产品列表的数组。 |
appFamily |
包含该应用的任何应用系列(或“默认”)。 |
appParentStatus |
应用父级的状态,例如“active”或“inactive” |
appType |
应用类型为“Developer”。 |
appParentId |
父级应用的 ID。 |
created_at |
应用的创建日期/时间戳。 |
created_by |
创建应用的开发者的电子邮件地址。 |
last_modified_at |
上次更新应用的日期/时间戳。 |
last_modified_by |
上次更新应用的开发者的电子邮件地址。 |
{app_custom_attributes} |
任何自定义应用属性。指定自定义属性的名称。 |
AppGroup 流变量
政策将填充以下包含 AppGroups 相关信息的流变量。仅当 verifyapikey.{policy_name}.app.appType
为“AppGroup”时,才会填充这些 AppGroup 属性。
这些变量均具有以下前缀:
verifyapikey.{policy_name}.appgroup
。
例如:
verifyapikey.{policy_name}.appgroup.name
可用变量包括:
变量 | 说明 |
---|---|
name |
AppGroup 的名称。 |
id |
AppGroup ID。 |
displayName |
AppGroup 显示名称。 |
appOwnerStatus |
应用所有者的状态:“active”“inactive”或“login_lock”。 |
created_at |
AppGroup 的创建日期/时间戳。 |
created_by |
创建 AppGroup 的开发者的电子邮件地址。 |
last_modified_at |
上次修改 AppGroup 的日期/时间戳。 |
last_modified_by |
上次修改 AppGroup 的开发者的电子邮件地址。 |
{appgroup_custom_attributes} |
任何自定义 AppGroup 属性。指定自定义属性的名称。 |
开发者流变量
政策将填充以下包含开发者相关信息的流变量。这些变量均具有以下前缀:
verifyapikey.{policy_name}.developer
例如:
verifyapikey.{policy_name}.developer.id
可用变量包括:
变量 | 说明 |
---|---|
id |
返回 {org_name}@@@{developer_id} |
userName |
开发者的用户名。 |
firstName |
开发者的名字。 |
lastName |
开发者的姓氏。 |
email |
开发者的电子邮件地址。 |
status |
开发者的状态,如 active、inactive 或 login_lock。 |
apps |
与开发者关联的应用数组。 |
created_at |
开发者的创建日期/时间戳。 |
created_by |
创建开发者的用户的电子邮件地址。 |
last_modified_at |
上次修改开发者的日期/时间戳。 |
last_modified_by |
修改开发者的用户的电子邮件地址。 |
{developer_custom_attributes} |
任何自定义开发者特性。指定自定义属性的名称。 |
分析变量
对有效的 API 密钥强制执行验证 API 密钥政策时,Analytics 中会自动填充以下变量。这些变量仅由验证 API 密钥政策和 OAuth 政策填充。
您可以将这些变量和值用作维度来构建 Analytics 报告,从而了解开发者和应用的使用模式。
apiproduct.name
developer.app.name
client_id
developer.id
创收流变量
对用户进行身份验证后,VerifyAPIKey 政策会检查所有已发布的费率方案,以根据生效和到期时间来确定哪个方案(如有)有效。如果发现有效的已发布费率方案,系统会填充以下流变量:
变量 | 说明 |
---|---|
mint.mintng_is_apiproduct_monetized |
如果找到有效的已发布费率方案,则为 true 。 |
mint.mintng_rate_plan_id |
费率方案 ID。 |
mint.rateplan_end_time_ms |
费率方案的到期时间。例如:1619433556408 |
mint.rateplan_start_time_ms |
费率方案的激活时间。例如:1618433956209 |
错误参考信息
本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 Apigee 设置的故障变量。在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅您需要了解的有关政策错误的信息和处理故障。
运行时错误
政策执行时可能会发生这些错误。
故障代码 | HTTP 状态 | 原因 |
---|---|---|
keymanagement.service.consumer_key_missing_api_product_association |
400 |
应用凭据缺少 API 产品关联。请将密钥的应用与 API 产品关联。请注意,这适用于所有应用类型,例如开发者应用和 AppGroup 应用。 |
keymanagement.service.DeveloperStatusNotActive |
401 |
创建具有您所用 API 密钥的开发者应用的开发者具有无效状态。将应用开发者的状态设置为无效时,将停用该开发者创建的所有开发者应用。具有适当权限的管理员用户(例如组织管理员)可以通过以下方式更改开发者的状态: |
keymanagement.service.invalid_client-app_not_approved |
401 |
与 API 密钥关联的开发者应用已被撤消。撤消的应用无法访问任何 API 产品,也无法调用由 Apigee 管理的任何 API。组织管理员可以使用 Apigee API 更改开发者应用的状态。请参阅生成密钥对或更新开发者应用状态。 |
oauth.v2.FailedToResolveAPIKey |
401 |
该政策要求在政策的 <APIKey> 元素中指定的变量中找到 API 密钥。 当预期变量不存在(无法解析)时,会发生此错误。 |
oauth.v2.InvalidApiKey |
401 |
Apigee 已收到 API 密钥,但该密钥无效。当 Apigee 在其数据库中查找密钥时,它必须与请求中发送的密钥完全匹配。如果 API 之前有效,请确保未重新生成密钥。如果重新生成密钥,且您尝试使用旧密钥,则会看到此错误。如需了解详情,请参阅通过注册应用来控制对 API 的访问权限。 |
oauth.v2.InvalidApiKeyForGivenResource |
401 |
Apigee 已收到 API 密钥,且该密钥有效;但是,它与通过产品与 API 代理关联的开发者应用中的已批准密钥不匹配。 |
部署错误
在您部署包含此政策的代理时,可能会发生这些错误。
错误名称 | 原因 |
---|---|
SpecifyValueOrRefApiKey |
<APIKey> 元素未指定值或密钥。 |
故障变量
发生运行时错误时,系统会设置这些变量。如需了解详情,请参阅您需要了解的有关政策错误的信息。
变量 | 地点 | 示例 |
---|---|---|
fault.name="fault_name" |
fault_name 是故障名称,如上面的运行时错误表中所列。故障名称是故障代码的最后一部分。 | fault.name Matches "FailedToResolveAPIKey" |
oauthV2.policy_name.failed |
policy_name 是抛出故障的政策的用户指定名称。 | oauthV2.VK-VerifyAPIKey.failed = true |
错误响应示例
{ "fault":{ "faultstring":"Invalid ApiKey", "detail":{ "errorcode":"oauth.v2.InvalidApiKey" } } }
{ "fault":{ "detail":{ "errorcode":"keymanagement.service.DeveloperStatusNotActive" }, "faultstring":"Developer Status is not Active" } }
故障规则示例
<FaultRule name="FailedToResolveAPIKey"> <Step> <Name>AM-FailedToResolveAPIKey</Name> </Step> <Condition>(fault.name Matches "FailedToResolveAPIKey") </Condition> </FaultRule>