本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
在本主题中,我们将讨论如何将外部生成的访问令牌、刷新令牌或授权代码导入 Apigee 令牌存储区。如果要配置 Apigee 来验证在 Apigee 之外生成的令牌,您可以使用此方法。
一般情况下,Apigee 将生成和存储 OAuth 令牌,并将其返回给调用应用。然后,调用应用会在请求服务时将该令牌传回 Apigee,Apigee 将通过 Operation = VerifyAccessToken 的 OAuthV2 政策验证该令牌是否有效。本主题介绍如何配置 Apigee 以存储在其他位置生成的 OAuth 令牌,同时保留令牌验证部分,就像该令牌由 Apigee 生成的一样。
示例
如需查看可演示本主题中介绍的技术的有效示例,请参阅 Apigee 委托令牌管理示例。
查看解释
假设您已有授权系统,并且您希望使用由该系统生成的令牌或代码值(而不是 Apigee 生成的 OAuth2 令牌或代码值)。则您可以使用替换的令牌或代码发出安全的 API 代理请求,Apigee 会对其进行验证,就像它们是 Apigee 生成的一样。
背景信息
通常情况下,Apigee 会生成一组随机的字母和数字作为令牌。Apigee 将其他数据该令牌与关联,例如令牌颁发时间、到期时间、令牌对其有效的 API 产品的列表以及范围。所有这些信息都可以在由配置了 Operation = GenerateAccessToken 的 OAuthV2 政策自动生成的响应中返回。响应如下所示:
{ "issued_at": "1469735625687", "application_name": "06947a86-919e-4ca3-ac72-036723b18231", "scope": "urn://example.com/read", "status": "approved", "api_product_list": "[implicit-test]", "api_product_list_json": ["implicit-test"], "expires_in": "1799", //--in seconds "developer.email": "joe@weathersample.com", "token_type": "BearerToken", "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk", "access_token": "zBC90HhCGmGlaMBWeZAai2s3za5j", "organization_name": "myorg", "refresh_token_expires_in": "0", //--in seconds "refresh_count": "0" }
Apigee 使用 access_token 值检索令牌元数据。 例如,假设 API 代理请求包含不记名令牌 zBC90HhCGmGlaMBWeZAai2s3za5j
。Apigee 使用令牌值检索令牌元数据以确定令牌是否有效。
按照本文所述的步骤,您可以将 Apigee 配置为存储其 access_token 值由外部服务生成的令牌。例如,假设您有一个 Apigee 外部的系统,它可以生成形式为“TOKEN-<16 位随机数字>”的令牌。此时,Apigee 存储的完整令牌元数据可能是:
{ "issued_at": "1469735625687", "application_name": "06947a86-919e-4ca3-ac72-036723b18231", "scope": "urn://example.com/read", "status": "approved", "api_product_list": "[implicit-test]", "api_product_list_json": ["implicit-test"], "expires_in": "1799", //--in seconds "developer.email": "joe@weathersample.com", "token_type": "BearerToken", "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk", "access_token": "TOKEN-1092837373654221", "organization_name": "myorg", "refresh_token_expires_in": "0", //--in seconds "refresh_count": "0" }
在这种情况下,应用可以向 API 代理发出包含不记名令牌 TOKEN-1092837373654221
的请求,Apigee 将能够对其进行验证。您可以将类似的导入模式应用于授权代码和刷新令牌。
验证客户端凭据
生成令牌的前提条件是验证请求客户端。默认情况下,Apigee 中的 OAuthV2/GenerateAccessToken 政策会隐式验证客户端凭据。通常,在请求 OAuthV2 令牌的请求中,client_id
和 client_secret
在授权标头中传递,通过 HTTP 基本授权进行编码(以冒号连接,然后进行 base64 编码)。Apigee 中的 OAuthV2/GenerateAccessToken 政策会解码该标头并查找 client_id
,然后验证传入的 client_secret
是否对该 client_id
有效。此机制有效的前提是 Apigee 知道这些凭据则,换言之,在 Apigee 内存储的开发者应用包含一个凭据,该凭据本身包含给定的 client_id
和 client_secret
。
如果客户端凭据不是由 Apigee 验证,则您必须设计 API 代理,以在生成令牌之前通过其他方法明确验证客户端。这通常通过连接到您网络中的远程端点的 ServiceCallout 政策实现。
无论是哪种情况,显式或是隐式,您都需要确保生成令牌的 API 代理首先验证客户端凭据。请注意,验证客户端与生成访问令牌是相互独立的。您可以对 Apigee 进行配置,使其同时执行两者,或执行其中之一,或两者都不执行。
如果您希望 Apigee 中的 OAuthV2/GenerateAccessToken 政策为 Apigee 存储区验证客户端凭据,请在政策配置中将 <ExternalAuthorization>
元素设置为 false
,或完全省略它。如果您想使用外部授权服务来明确验证客户端凭据,请将 <ExternalAuthorization>
设置为 true
。
虽然 Apigee 可能不验证客户端凭据,但 Apigee 仍需知道和管理 client_id
。Apigee 中的每个 access_token(无论是由 Apigee 生成还是由外部系统生成并导入 Apigee)都必须与客户端应用关联(由 client_id
指示)。因此,即使 Apigee 中的 OAuthV2/GenerateAccessToken 政策不验证 client_id
和 client_secret
是否匹配,该政策也会验证 client_id
是否有效、存在以及未被撤消。因此,作为前提条件设置步骤,您可能需要通过 Apigee 管理 API 导入 client_id
。
Apigee 上第三方 OAuth 的政策流
要在 Apigee 中使用来自第三方 OAuth 系统的令牌,则生成访问令牌的流程应遵循以下模式之一。
客户端凭据的外部验证
- ServiceCallout,验证入站客户端凭据,并获取外部令牌。
- ExtractVariables 或 JavaScript 步骤,从响应中提取外部生成的令牌。
- AssignMessage,设置名为
oauth_external_authorization_status
的特殊已知变量。要表明客户端凭据有效,该值必须为 true。 - OAuthV2/GenerateAccessToken,
<ExternalAuthorization>
元素设置为true
,并且至少包含<ExternalAccessToken>
、<ExternalRefreshToken>
或<ExternalAuthorizationCode>
中的一个。
客户端凭据的内部验证
- ServiceCallout,获取外部令牌。
- ExtractVariables 或 JavaScript 步骤,从响应中提取外部生成的令牌。
- OAuthV2/GenerateAccessToken,
<ExternalAuthorization>
元素设置为false
,并且至少包含<ExternalAccessToken>
、<ExternalRefreshToken>
或<ExternalAuthorizationCode>
中的一个。
关于流和政策配置的说明
-
如果您想使用外部系统验证客户端凭据,那么您需要负责开发相应的政策流。通常,您可以使用 ServiceCallout 政策将外部识别的凭据发送到外部身份验证服务。外部身份验证服务通常会返回响应;如果凭据有效,还会提供访问令牌。
-
ServiceCallout 之后,API 代理需要解析响应以提取有效状态,以及外部生成的 access_token 和可能的 refresh_token。
-
在 OAuthV2/GenerateAccessToken 政策中,将
<StoreToken>
元素设置为true
,并根据情况将<ExternalAuthorization>
元素设置为true
或false
。当 OAuthV2/GenerateAccessToken 政策执行时,它会读取变量
oauth_external_authorization_status
。如果设置了此变量且值为 true,则 Apigee 不会尝试验证客户端凭据。如果未设置该变量或值不是 true,则 Apigee 将尝试验证客户端凭据。 -
OAuthV2 政策有三个元素,可供您指定要导入的外部数据:
<ExternalAccessToken>
、<ExternalRefreshToken>
和<ExternalAuthorizationCode>
。每个元素都接受一个流变量。Apigee 政策将读取该变量,以找出外部生成的访问令牌、刷新令牌或授权代码。您需要自行实现相关政策和逻辑,以将外部令牌或代码放入相应的变量中。例如,OAuthV2 政策中的以下配置指示 Apigee 在名为
external_token
的上下文变量中查找令牌。<ExternalAccessToken>external_token</ExternalAccessToken>
您还需要执行设置该变量的前一个步骤。
-
设置
oauth_external_authorization_status
变量的一个常用方法是使用具有 AssignVariable 元素的 AssignMessage 政策,如下所示:<AssignMessage name="AssignMessage-SetVariable"> <DisplayName>Assign Message - Set Variable</DisplayName> <AssignVariable> <Name>oauth_external_authorization_status</Name> <Value>true</Value> </AssignVariable> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </AssignMessage>
请记住,此政策必须在 Operation = GenerateAccessToken 的 OAuthV2 政策之前。
OAuthV2 政策示例
以下 OAuthV2 政策会生成访问令牌(假设 Apigee 在流变量 external_access_token
中找到令牌值)。
<OAuthV2 name="OAuth-v20-Store-External-Token"> <DisplayName>OAuth v2.0 1</DisplayName> <Attributes/> <ExternalAccessToken>external_access_token</ExternalAccessToken> <ExternalAuthorization>true</ExternalAuthorization> <Operation>GenerateAccessToken</Operation> <GenerateResponse enabled="true"> <Format>FORM_PARAM</Format> </GenerateResponse> <ReuseRefreshToken>false</ReuseRefreshToken> <StoreToken>true</StoreToken> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <ExpiresIn ref='flow.variable'>2400000</ExpiresIn> </OAuthV2>
从理论上讲,您可以对任何第三方 OAuth2 授权服务应用此模式。