实现授权代码授权类型

您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档
信息

授权代码是最常用的 OAuth 2.0 授权类型之一。授权代码流是一种“三足式 OAuth”配置。在此配置中,用户通过资源服务器进行身份验证,并允许应用访问其受保护的资源,而无需将用户名/密码泄露给客户端应用。

关于此主题

本主题简要介绍 OAuth 2.0 授权授予类型流,并讨论如何在 Apigee Edge 上实现此流。

视频

观看一个简短视频,了解如何使用 OAuth 2.0 授权授予类型来保护您的 API。

用例

此授权类型适用于没有与 API 提供商具有可信业务关系的第三方开发者编写的应用。例如,注册公共 API 项目的开发者通常不应受信任。采用这种授权类型时,应用绝不会与应用共享资源服务器上的用户凭据。

代码示例

您可以在 GitHub 上的 api-platform-samples 代码库中找到 Apigee Edge 授权代码授权类型的完整工作实现示例。请参阅 api-platform-samples/sample-proxies 目录中的 oauth-advanced 示例。如需了解示例详情,请参阅 README 文件。

流程图

以下流程图说明了 Apigee Edge 用作授权服务器的授权代码 OAuth 流。

提示:要查看此图表的较大版本,请右键点击并在新的标签页中打开它,也可以将其保存并在图片查看器中打开。

授权代码流中的步骤

以下是在 Apigee Edge 用作授权服务器的情况下实现授权代码授权类型所需的步骤的摘要。请记住,此流的关键是客户端永远不会在资源服务器上看到用户凭据。

前提条件:客户端应用必须在 Apigee Edge 上注册才能获得客户端 ID 和客户端密钥。如需了解详情,请参阅注册客户端应用

1. 用户启动流

当应用需要从资源服务器(例如社交媒体网站上的联系人列表)访问用户受保护的资源时,它会向 Apigee Edge 发送 API 调用,以验证客户端 ID;如果有效,会将用户的浏览器重定向至用户输入凭据的登录页面。API 调用包含客户端应用在注册时获得的信息:客户端 ID 和重定向 URI。

2. 用户输入凭据

用户现在会看到一个登录页面,要求他们输入登录凭据。如果登录成功,请继续执行下一步。

3. 用户表示同意

在此步骤中,用户同意应用访问其资源。同意表单通常包含范围选择,用户可在其中选择应用可以在资源服务器上执行的操作。例如,用户可以授予只读权限或让应用可更新资源的权限。

4. 登录应用向 Apigee Edge 发送请求

如果登录和同意成功,则登录应用会将数据发布到 Apigee Edge 的 /authorizationcode 端点。数据包括重定向 URI、客户端 ID、范围、希望包含的任何特定于用户的信息,以及表示登录成功的指示。

5. Apigee Edge 生成授权代码

当 Edge 在其 /authorizationcode 端点上收到登录应用发出的 GET 请求时,会发生以下两种情况。首先,Edge 确定登录是否成功(通过检查 HTTP 状态或一些其他方式)。接着 Edge 检查确保从登录应用发送的重定向 URI 与向 Apigee Edge 注册应用时指定的重定向 URI 匹配。如果一切正常,Edge 将生成授权代码。例如:

http://myorg-test.apigee.net/oauth/authorizationcode?client_id={consumer_key}&response_type=code&redirect_uri={redirect_uri}&scope=scope1%20scope2&state={some_string}

6. Edge 将授权代码发送回客户端

Edge 将 302 重定向以及作为查询参数附加的授权代码发送到客户端。

7. 客户端检索授权代码并从 Edge 请求访问代码

现在,有了有效的授权代码,客户端就可以从 Edge 请求访问令牌。具体做法是发布客户端 ID 和客户端密钥(在 Edge 上注册应用时获取)、授权类型和范围。通过添加客户端 ID 和密钥,Apigee Edge 可以验证该客户端应用是否为已注册的应用。例如:

$ curl https://{org_name}-test.apigee.net/my_oauth_proxy/accesstoken?code=Xyz123&grant_type=authorization_code -X POST -d 'client_id=bBGAQrXgivA9lKu7NMPyoYpKNhGar6K&client_secret=hAr4GngA9vAyvI4'

8. 客户端收到访问令牌

如果成功,Edge 会向客户端返回一个访问令牌。访问令牌将具有有效期,并且仅在用户同意应用访问其资源时指定的范围才有效。

9. 客户端调用受保护的 API

现在,通过有效的访问代码,客户端便可以向受保护的 API 发出调用。在这种情况下,系统会向 Apigee Edge(代理)发出请求,Edge 负责在将 API 调用传递到目标资源服务器之前验证访问令牌。访问令牌在 Authorization 标头中传递。例如:

$ curl -H "Authorization: Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

配置流和政策

作为授权服务器,Edge 需要处理多种 OAuth 请求:访问令牌、授权代码、刷新令牌、登录页面重定向等。配置这些端点有两个基本步骤:

  • 创建自定义流
  • 添加和配置 OAuthV2 政策

自定义流配置

您通常配置此授权类型流,以便流的每个步骤或“分支”都由 Apigee Edge 代理中的流定义。每个流都有一个端点和一个执行所需的 OAuth 特定任务(例如生成授权代码或访问令牌)的政策。例如,如以下 XML 中所示,/oauth/authorizationcode 端点具有一个名为 GenerateAuthCode 的关联政策(是指定了 GenerateAuthorizationCode 操作的 OAuthV2 政策)。

显示流配置的最简单方法是使用 XML 示例。如需了解每个流,请参阅内联注释。这是一个示例。您可以根据需要配置流和路径的名称。如需大致了解创建此类自定义流所需的步骤,另请参阅配置 OAuth 端点和政策

另请参阅 GitHub 上的实现示例

<Flows>
<Flow name="RedirectToLoginApp">
<!--
Publish this URI to developers to use for their 'login' link
-->
<Condition>proxy.pathsuffix == "/oauth/authorize"</Condition>
<Request>
<Step><Name>RedirectToLoginPage</Name></Step>
</Request>
</Flow>
<Flow name="GetAuthCode">
<!--
Call this URL from your Login app after you authenticate the user.
The policy will automatically return the auth code in the response to the
redirect_uri registered by the calling app
-->
<Condition>proxy.pathsuffix == "/oauth/authorizationcode"</Condition>
<Request>
<Step><Name>GenerateAuthCode</Name></Step>
</Request>
</Flow>
<Flow name="GetAccessToken">
<!-- This policy flow is triggered when the URI path suffix
matches /oauth/accesstoken. Publish this URL to app developers
to use when obtaining an access token using an auth code
-->
<Condition>proxy.pathsuffix == "/oauth/accesstoken"</Condition>
<Request>
<Step><Name>GenerateAccessToken</Name></Step>
</Request>
</Flow>
</Flows>

使用政策配置流

每个端点都有关联的政策。我们来看一些政策示例。如需大致了解向代理端点添加 OAuthV2 政策所需的步骤,请参阅配置 OAuth 端点和政策

登录重定向

这是 /oauth/authorize 路径。附加的政策负责将用户重定向到登录应用,在登录应用中,最终用户可以安全地进行身份验证并授权客户端应用访问其受保护的资源,而无需将用户名和密码泄露给客户端应用。您可以通过服务调用程序政策、JavaScript、Node.js 或其他方式实现此目的。

执行请求的 API 调用是 GET,需要查询参数 client_id、response_type、redirect_uri、scope 和 state。

$ curl http://myorg-test.apigee.net/oauth/authorize?client_id={consumer_key}&response_type=code&redirect_uri={redirect_uri}&scope=scope1%20scope2&state={some_string}

获取授权代码

这是 /oauth/authorizationcode 路径。它使用指定了 GenerateAuthorizationCode 操作的 OAuthV2 政策。

<OAuthV2 async="false" continueOnError="false" enabled="true" name="GetAuthCode">
    <DisplayName>GetAuthCode</DisplayName>
    <Operation>GenerateAuthorizationCode</Operation>
    <ExpiresIn>600000</ExpiresIn>
    <GenerateResponse/>
</OAuthV2>

用于获取授权代码的 API 调用为 GET,需要查询参数 client_id、response_type 以及可选的 scope 和 state,如下例所示:

$curl http://myorg-test.apigee.net/oauth/authorizationcode?client_id={consumer_key}&response_type=code&scope=scope1%20scope2&state={some_string}

获取访问令牌

此政策将附加到 /oauth/accesstoken 路径。它使用指定了 GenerateAccessCode 操作的 OAuthV2 政策。在这种情况下,grant_type 参数应用作查询参数:

<OAuthV2 name="GetAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>360000000</ExpiresIn> 
    <SupportedGrantTypes> 
        <GrantType>authorization_code</GrantType> 
    </SupportedGrantTypes> 
    <GrantType>request.queryparam.grant_type</GrantType> 
    <GenerateResponse/> 
</OAuthV2>

用于获取访问代码的 API 调用为 POST,必须包含 client_id、client_secret、grant_type=authorization_code 以及可选的 scope。例如:

$ curl https://{org_name}-test.apigee.net/oauth/accesstoken?grant_type=authorization_code -X POST -d 'client_id=bBGAQrXgivA9lKu7NMPyoYpVKNhGar6K&client_secret=hAr4Gn0gA9vAyvI4'

这只是一个基本摘要。生产示例包括许多其他用于构建网址、执行转换和执行其他任务的政策。请参阅 GitHub 上的示例,查看完整工作项目。

附加验证访问令牌政策

将 VerifyAccessToken 政策(指定了 VerifyAccessToken 操作的 OAuthV2 政策)附加到访问受保护 API 的任何流的开头,以便在任何受保护的资源收到请求时执行。Edge 检查确保每个请求都有一个有效的访问令牌。否则,将返回错误。如需了解基本步骤,请参阅验证访问令牌

<OAuthV2 async="false" continueOnError="false" enabled="true" name="VerifyAccessToken">
    <DisplayName>VerifyAccessToken</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <SupportedGrantTypes/>
    <GenerateResponse enabled="true"/>
    <Tokens/>
</OAuthV2>

调用受保护的 API

如需调用使用 OAuth 2.0 安全性保护的 API,您需要提供有效的访问令牌。正确的模式是将令牌添加到 Authorization 标头,如下所示:请注意,访问令牌也称为“不记名令牌”。

$ curl -H "Authorization: Bearer UAj2yiGAcMZGxfN2DhcUbl9v8WsR" \
  http://myorg-test.apigee.net/v0/weather/forecastrss?w=12797282 

另请参阅发送访问令牌