使用 OAuth 2.0 保护 API

本页面适用于 ApigeeApigee Hybrid

查看 Apigee Edge 文档。

本教程介绍如何使用 OAuth 2.0 访问令牌保护 API 代理。

准备工作

如需完成本教程,您必须有权访问您拥有权限的 Apigee 组织:

  • 创建和部署 API 代理
  • 创建 API 产品
  • 创建开发者应用

您还必须具有正确配置的环境组主机名,以便进行 Apigee API 代理调用。如果您不确定要使用哪个环境组主机名,请咨询您的 Apigee 管理员。

部署 OAuth 2.0 代理

我们在 GitHub 上提供了一个 API 代理,用于配置 OAuth 2.0 访问令牌。按照以下步骤下载此 API 代理并将其部署到您的环境:

  1. oauth 示例 API 代理下载到文件系统上的目录中。
  2. 转到 Apigee 界面,然后登录并选择 Apigee 组织。
  3. 在左侧导航栏中,选择开发 > API 代理
  4. 点击新建
    创建代理按钮
  5. 在“创建代理”向导中,选择上传代理软件包 (Upload proxy bundle)。
  6. 选择您下载的 oauth.zip 文件,然后点击下一步
  7. 点击创建
  8. 构建完成后,点击修改代理 (Edit proxy) 以在 API 代理编辑器中查看新代理。
  9. 点击部署
  10. 选择要部署到的修订版本和环境。您可以将服务账号字段留空。
  11. 点击部署

您已成功下载访问令牌生成 API 代理,并将其部署到您的 Apigee 组织中。

查看 OAuth 2.0 流程和政策

花些时间检查 OAuth 2.0 政策配置。

新版代理编辑器

接下来,您将深入了解 API 代理包含的内容。

  1. 在 API 代理编辑器中,点击开发标签页。

    “开发”标签页中显示的政策。

    在左侧窗格中,您会看到两个政策。您还会在“代理端点”部分看到两个 POST 流程。

  2. 点击代理端点下的 AccessTokenClientCredential。 文本编辑器显示 AccessTokenClientCredential 条件流程的 XML 代码:
    <Flow name="AccessTokenClientCredential">
        <Description/>
        <Request>
            <Step>
                <Name>GenerateAccessTokenClient</Name>
            </Step>
        </Request>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/accesstoken") and (request.verb = "POST")</Condition>
    </Flow>
    

    流程是 API 代理中的一个处理步骤。在这种情况下,当符合特定条件时就会触发流程(称为“条件流程”)。在 <Condition> 元素中定义的条件表示,如果 API 代理调用是对 /accesstoken 资源进行的,并且请求动词是 POST,则执行 GenerateAccessTokenClient 政策,该政策生成访问令牌。

  3. 现在我们来看看条件流程将触发的政策。点击请求窗格中的 GenerateAccessTokenClient 政策: 点击 AccessTokenClientCredential 下方的 GenerateAccessTokenClient。

经典版代理编辑器

接下来,您将深入了解 API 代理包含的内容。

  1. 在 API 代理编辑器中,点击开发标签页。在左侧导航窗格中,您会看到两个政策。您还会在“代理端点”部分看到两个 POST 流程。
  2. 点击代理端点下的 AccessTokenClientCredential
    条件流的 XML 代码。

    在 XML 代码视图中,您会看到一个名为 AccessTokenClientCredentialFlow

    <Flow name="AccessTokenClientCredential">
        <Description/>
        <Request>
            <Step>
                <Name>GenerateAccessTokenClient</Name>
            </Step>
        </Request>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/accesstoken") and (request.verb = "POST")</Condition>
    </Flow>
    

    流程是 API 代理中的一个处理步骤。在这种情况下,当符合特定条件时就会触发流程。在 <Condition> 元素中定义的条件表示,如果 API 代理调用是对 /accesstoken 资源进行的,并且请求动词是 POST,则执行 GenerateAccessTokenClient 政策,该政策生成访问令牌。

  3. 现在我们来看看条件流程将触发的政策。点击流程图中的 GenerateAccessTokenClient 政策图标。

    流程图中的 GenerateAccessTokenClient 政策图标。

系统会显示以下 XML 配置:

<OAuthV2 name="GenerateAccessTokenClient">
    <!-- This policy generates an OAuth 2.0 access token using the client_credentials grant type -->
    <Operation>GenerateAccessToken</Operation>
    <!-- This is in milliseconds, so expire in an hour -->
    <ExpiresIn>3600000</ExpiresIn>
    <SupportedGrantTypes>
        <!-- This part is very important: most real OAuth 2.0 apps will want to use other
         grant types. In this case it is important to NOT include the "client_credentials"
         type because it allows a client to get access to a token with no user authentication -->
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <GrantType>request.queryparam.grant_type</GrantType>
    <GenerateResponse/>
</OAuthV2>

配置包括以下内容:

  • <Operation> 可以是几个预定义值之一,用于定义政策要执行的操作。在此情况下,它将会生成访问令牌。
  • 令牌将在生成后 1 小时(3600000 毫秒)过期。
  • <SupportedGrantTypes> 中,应使用的 OAuth 2.0 <GrantType>client_credentials(交换 OAuth 2.0 令牌的使用方密钥和密码)。
  • 第二个 <GrantType> 元素指示政策根据 OAuth 2.0 规范的要求在 API 调用中的何处查找授权类型参数。(此授权类型参数稍后会在 API 调用中看到)。授权类型还可以 HTTP 标头 (request.header.grant_type) 的形式或作为表单参数 (request.formparam.grant_type) 发送。

目前,您无需对 API 代理执行任何其他操作。在后续步骤中,您将使用此 API 代理生成 OAuth 2.0 访问令牌。但首先,您还需要执行以下操作:

  • 使用 OAuth 2.0 创建您真正希望保护的 API 代理。
  • 再创建几个工件,这会导致交换访问令牌所需的使用方密钥和使用方密码。

创建受保护的 API 代理

现在,您将创建要保护的 API 代理。此 API 调用会返回您所需的内容。在此情况下,API 代理将调用 Apigee 的 mocktarget 服务来返回您的 IP 地址。但是,只有当您通过 API 调用传递有效的 OAuth 2.0 访问令牌时,您才会看到。

您在此处创建的 API 代理将包含一个政策,用于检查请求中的 OAuth 2.0 令牌。

  1. 在左侧导航栏中,选择开发 > API 代理
  2. 点击新建
    创建代理按钮
  3. 在“构建代理”向导中,选择反向代理(最常见) (Reverse proxy (most common))。
  4. 请使用以下操作配置代理:
    在此字段中 执行该操作
    代理名称 输入:helloworld_oauth2
    项目基本路径

    更改为:/hellooauth2

    项目基本路径是用于向 API 代理发出请求的网址的一部分。

    现有 API

    输入:https://mocktarget.apigee.net/ip

    这定义了 Apigee 在对 API 代理的请求上调用的目标网址。

    说明 输入:hello world protected by OAuth 2.0
  5. 点击下一步
  6. 通用政策 (Common policies) 页面上,执行以下操作:
    在此字段中 执行该操作
    安全授权 请选择:
    • OAuth 2.0

    这些选项非常方便。这些选项会自动向您的 API 代理添加两项政策,并创建 API 产品。

  7. 点击下一步
  8. 摘要页面的可选部署下,选择一个环境,然后点击创建和部署
  9. 点击修改代理 (Edit proxy),以显示 API 代理的概览页面。
    系统会自动为您部署 API 代理。(部署可能需要一些时间才能完成。)

查看政策

我们来详细了解一下您创建的内容。

新版代理编辑器

  1. 在 API 代理编辑器中,点击开发标签页。您将看到 API 代理的请求流程中添加了两个政策:
    • 验证 OAuth v2.0 访问令牌 –检查 API 调用以确保存在有效的 OAuth 2.0 令牌。
    • 移除标头授权 –“分配消息”政策,该政策将在检查访问令牌后将其删除,以免将其传递给目标服务。(如果目标服务需要 OAuth 2.0 访问令牌,您将不会使用此政策)。
  2. 点击右侧窗格中的 Verify OAuth v2.0 访问令牌图标,然后在文本编辑器中查看其下方的 XML。

经典版代理编辑器

  1. 在 API 代理编辑器中,点击开发标签页。您将看到 API 代理的请求流程中添加了两个政策:
    • 验证 OAuth v2.0 访问令牌 –检查 API 调用以确保存在有效的 OAuth 2.0 令牌。
    • 移除标头授权 –“分配消息”政策,该政策将在检查访问令牌后将其删除,以免将其传递给目标服务。(如果目标服务需要 OAuth 2.0 访问令牌,您将不会使用此政策)。
  2. 点击流程视图中的验证 OAuth v2.0 访问令牌图标,然后在代码窗格中查看其下方的 XML。

    验证 OAuth v2.0 访问令牌代码

<OAuthV2 async="false" continueOnError="false" enabled="true" name="verify-oauth-v2-access-token">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <Operation>VerifyAccessToken</Operation>
</OAuthV2>

请注意,<Operation>VerifyAccessToken。操作定义了政策应该执行的操作。在这种情况下,它将检查请求中的有效 OAuth 2.0 令牌。

添加 API 产品

如需获取 OAuth 2.0 访问令牌,您需要创建三个 Apigee 实体:API 产品、开发者和开发者应用。首先,创建 API 产品:

  1. 选择发布 > API 产品
  2. 点击+创建
  3. 输入 API 产品的产品详细信息。
    字段 说明
    名称 API 产品的内部名称。请勿在名称中指定特殊字符。
    注意:API 产品一经创建,便无法再修改其名称。
    显示名 API 产品的显示名。显示名用于界面中,您可以随时进行修改。如果未指定,则系统会使用 Name 值。此字段会使用 Name 值自动填充;您可以修改或删除其内容。显示名可以包含特殊字符。
    说明 API 产品的说明。
    环境 API 产品将允许访问的环境。选择要在其中部署 API 代理的环境。
    访问权限 选择公开
    自动批准访问请求 从任何应用启用此 API 产品的密钥请求的自动批准。
    配额 在本教程中忽略。
    允许的 OAuth 2.0 范围 在本教程中忽略。
  4. 操作部分中,点击添加操作
  5. 在“API 代理”字段中,选择您刚刚创建的 API 代理。
  6. 在“路径”字段中,输入“/”。忽略其他字段。
  7. 点击保存以保存该操作。
  8. 点击保存以保存该 API 产品。

将开发者和应用添加到您的组织

接下来,您将模拟开发者注册使用 API 的工作流程。理想情况下,开发者可通过开发者门户注册自己及其应用。但在此步骤中,您将以管理员的身份添加开发者和应用。

开发者将拥有一个或多个调用您的 API 的应用,并且每个应用都具有唯一的使用方密钥和使用方密码。每个应用的密钥/密码还为您(API 提供商)提供了对 API 访问更精细的控制,以及对 API 流量的更精细的分析报告,因为 Apigee 知道哪个开发者和应用属于哪个 OAuth 2.0 令牌。

创建一个开发者

我们来创建一个名为“Nigel Tufnel”的开发者名称。

  1. 在菜单中选择 Publish > Developers
  2. 点击 + 开发者
  3. 在“新开发者”窗口中输入以下内容:
    在此字段中 输入
    名字 Nigel
    姓氏 Tufnel
    用户名 nigel
    电子邮件 nigel@example.com
  4. 点击保存

注册一个应用

让我们为 Nigel 创建一个应用。

  1. 选择发布 > 应用
  2. 点击 + 应用
  3. 在“新应用”窗口中输入以下内容:
    在此字段中 执行该操作
    名称显示名 输入:nigel_app
    开发者 点击开发者,然后选择:Nigel Tufnel (nigel@example.com)
    回调网址备注 留空
  4. 产品下,点击添加产品
  5. 添加您刚创建的 API 产品。
  6. 点击创建

获取使用方密钥和使用方密码

现在,您将获取将用于交换 OAuth 2.0 访问令牌的使用方密钥和使用方密码。

  1. 确保显示 nigel_app 页面。如果没有,请在“应用”页面(发布 > 应用)上点击 nigel_app
  2. 在 Nigel_app 页面上,点击密钥密码列中的显示。请注意,密钥/密文与您之前创建的 API 产品相关联。

  3. 选择并复制密钥和密码。将其粘贴到临时文本文件中。您将在后面的步骤中使用这些密钥和密码,以便在调用 API 代理时将这些凭据交换为 OAuth 2.0 访问令牌。

尝试调用 API 以获取 IP 地址(失败!)

尝试调用刚创建的受保护 API 代理。请注意,您不会在调用中传递 OAuth 2.0 访问令牌。

其中,YOUR ENV_GROUP_HOSTNAME 是环境组主机名。请参阅查找环境组主机名

由于 API 代理使用 Verify OAuth v2.0 Access Token 政策检查请求中的有效 OAuth 2.0 令牌,因此调用应会失败并显示以下消息:

{"fault":{"faultstring":"Invalid access token","detail":{"errorcode":"oauth.v2.InvalidAccessToken"}}}

这种情况下,失败是好消息!这表示您的 API 代理更加安全。只有具有有效 OAuth 2.0 访问令牌的可信应用才能成功调用此 API。

获取 OAuth 2.0 访问令牌

接下来,您将使用复制并粘贴到文本文件中的密钥和密文,并用其换取 OAuth 2.0 访问令牌。您现在要对导入的 API 示例代理 oauth 进行 API 调用,该代理将生成 API 访问令牌。

使用该密钥和密文进行以下 cURL 调用(请注意,协议为 https):

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
"https://YOUR ENV_GROUP_HOSTNAME/oauth/client_credential/accesstoken?grant_type=client_credentials" \
-d "client_id=CLIENT_KEY&client_secret=CLIENT_SECRET"

请注意,如果您使用 Postman 等客户端发起调用,则 client_idclient_secret 将进入请求的正文中,并且必须为 x-www-form-urlencoded

您应该得到如下所示的响应:

{
  "issued_at" : "1466025769306",
  "application_name" : "716bbe61-f14a-4d85-9b56-a62ff8e0d347",
  "scope" : "",
  "status" : "approved",
  "api_product_list" : "[helloworld_oauth2-Product]",
  "expires_in" : "3599", //--in seconds
  "developer.email" : "nigel@example.com",
  "token_type" : "BearerToken",
  "client_id" : "xNnREu1DNGfiwzQZ5HUN8IAUwZSW1GZW",
  "access_token" : "GTPY9VUHCqKVMRB0cHxnmAp0RXc0",
  "organization_name" : "myOrg",
  "refresh_token_expires_in" : "0", //--in seconds
  "refresh_count" : "0"
}

您获得了 OAuth 2.0 访问令牌!复制 access_token 值(不带引号)并将其粘贴到您的文本文件。稍后您将用到它。

刚刚出现了什么情况?

请记住,当您查看 OAuth 代理中的“条件流程”时,如果资源 URI 为/accesstoken 并且请求动词是 POST,以执行 GenerateAccessTokenClient 生成访问令牌的 OAuth 2.0 政策?您的 cURL 命令符合这些条件,因此执行 OAuth 2.0 政策。它会验证您的使用方密钥和使用方密码,并将其交换为在 1 小时内到期的 OAuth 2.0 令牌。

使用访问令牌调用 API(成功!)

您拥有访问令牌之后,就可以使用该令牌来调用 API 代理了。进行以下 cURL 调用。替换 Apigee 组织名称和访问令牌。

curl https://YOUR ENV_GROUP_HOSTNAME/hellooauth2 -H "Authorization: Bearer TOKEN"

现在,您应该成功地调用了返回您的 IP 地址的 API 代理。例如:

{"ip":"::ffff:192.168.14.136"}

您可以重复该 API 调用接近一小时,之后访问令牌将过期。要在一小时之后发起调用,您需要使用上一步生成新的访问令牌。

恭喜!您已创建 API 代理,并要求在调用中包含有效的 OAuth 2.0 访问令牌,从而保护它。

相关主题