

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# OAuth 2.0 授权 URL 会话绑定
<a name="oauth2-authorization-url-session-binding"></a>

AgentCore Identity 为您的代理应用程序提供 OAuth 2.0 访问令牌检索，以访问受身份提供商/授权服务器保护的第三方应用程序供应商或资源。如果应用程序或资源要求用户使用 OAuth 授权代码流进行明确授权，Id AgentCore entity 会生成一个授权 URL 供用户导航并同意访问。然后，在用户表示同意后， AgentCore Identity 代表用户从应用程序或资源中获取访问令牌，并将其存储在 AgentCore 身份令牌库中。

但是，由于用户可能会意外地将授权 URL 发送给其他用户并获得对该用户应用程序或资源的访问权限，因此您的应用程序必须验证发起授权请求的用户是否仍与对该应用程序或资源授予许可的用户相同。为此，您需要使用处理用户验证的 Id AgentCore entity 注册一个公开可用的 HTTPS 应用程序终端节点。

## 会话绑定的工作原理
<a name="how-session-binding-works"></a>

以下流程图和相应步骤显示了 OAuth 2.0 授权 URL 会话绑定过程：

![OAuth 2.0 授权 URL 会话绑定流程图](https://docs.amazonaws.cn/bedrock-agentcore/latest/devguide/images/identity-session-binding.png)


1.  **调用代理 **-当原始代理用户想要访问拥有的某些应用程序或资源时，您的代理代码会调用 `GetResourceOauth2Token` API 来检索授权 URL。 he/she 

1.  **生成授权 URL ** — I AgentCore dentity 生成授权 URL 和会话 URI，供用户导航并同意访问。

1.  **授权并获取访问令牌 **-用户导航到授权 URL 并同意您的代理访问 his/her 资源。之后， AgentCore Identity 使用包含授权请求原始用户的信息将用户的浏览器重定向到您的 HTTPS 应用程序终端节点。此时，您的 HTTPS 应用程序终端节点确定原始代理用户是否仍与应用程序的当前登录用户相同。如果它们匹配，您的应用程序终端节点会调用，`CompleteResourceTokenAuth`这样 Id AgentCore entity 就可以提取和存储访问令牌。

1.  **Re-invoke 代理获取访问令牌 **-应用程序返回有效响应后，您的代理应用程序将能够检索最初为用户请求的 OAuth2.0 访问令牌。如果用户不匹配，则您的应用程序只会不执行任何操作或记录尝试。

通过允许您的应用程序终端节点验证用户身 AgentCore 份，Identity 允许您的代理应用程序确保发起授权请求的用户和同意访问的用户始终是同一个用户。

## 实施详情
<a name="implementation-details"></a>

以下步骤将引导您设置工作负载身份、OAuth 2.0 凭据提供商以及来自资源提供商的 OAuth 2.0 应用程序客户端，用于为代理应用程序检索 OAuth 2.0 访问令牌。

您可以将示例代码作为工作应用程序的示例：[OAuth 2.0 回调服务器实现。](https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-features/05-authenticate-and-authorize/02-outbound-auth/02-outbound-auth-3lo/oauth2_callback_server.py)

**重要**  
当您在本地环境`agentcore dev`中使用 AgentCore CLI 时，为了简化本地开发和测试，CLI 托管回调端点并代表您调用 `CompleteResourceTokenAuth` API 来验证用户会话以获取 OAuth 2.0 访问令牌，因此您可以跳过以下设置中的步骤 1、2 和 4。但是，将代理代码部署到 AgentCore 运行时时，连接到代理运行时的 Web 应用程序本身必须托管一个可公开访问的 HTTPS 回调端点，必须`UpdateWorkloadIdentity`使用 Runt AgentCore ime 提供的代理 ID 调用将回调端点注册为工作负载身份，然后在验证当前用户的浏览器会话后调用 `CompleteResourceTokenAuth` API 以保护您的 OAuth 2.0 授权流程。`AllowedResourceOAuth2ReturnUrl`

 **实现 OAuth 2.0 授权 URL 会话绑定 ** 

1.  **创建应用程序 URL ** — 对于面向用户的浏览器应用程序，创建并托管一个新的 URL，该网址可从用户浏览器访问，并且可以接受来自浏览器重定向的请求。此页面应重定向到用户可以继续进行代理会话的应用程序页面，或者呈现一些基本的网页，指示用户返回其当前处于活动状态的代理会话。在实施的后续部分中，此页面用于验证当前用户的活动会话，因此此页面还应该能够访问和维护您的应用程序用户会话数据。

   例如，您的应用程序可能会让其用户在主应用程序页面上与代理进行交互，例如`https://myagentapp.com/assistant`。你需要公开一个像`https://myagentapp.com/callback`这样的新网址，现在将重定向到主应用程序页面。稍后将在遵循本指南时更新`/callback`端点中的实际代码逻辑。

1.  **使用应用程序 URL 更新工作负载身份 ** —（如果通过 AgentCore CLI 进行本地测试，则可以跳过）创建并托管了要重定向到的 Id AgentCore entity 的应用程序 URL 后，请更新您的工作负载身份，以便将应用程序 URL 注册为`AllowedResourceOauth2ReturnUrl`。确保所使用的 IAM 凭证有权调用`CreateWorkloadIdentity`或`UpdateWorkloadIdentity`取决于您是创建新的工作负载身份还是更新现有工作负载身份。
**注意**  
对于由 AgentCore Runtime 或 Gateway 代表您创建的工作负载身份，工作负载标识名称将对应于服务颁发的运行时 ID 或网关 ID。

   示例 `UpdateWorkloadIdentity` API 调用：

   ```
   aws bedrock-agentcore-control update-workload-identity --name GoogleCalendarAgent \
   --allowed-resource-oauth2-return-urls https://myagentapp.com/callback
   ```

1.  **在 “ AgentCore 身份” 中创建 OAuth 2.0 凭据提供商 ** — 要完全注册 OAuth 2.0 凭据提供商，您需要具有调用和的权限。`CreateOauth2CredentialProvider` `UpdateOauth2CredentialProvider`按照以下步骤进行操作：
   + `CreateOauth2CredentialProvider`使用占位符调用客户端 ID 和客户端密钥。
   + API 响应将包含 OAuth 回调（重定向）网址，例如：`https://bedrock-agentcore.amazonaws.com/identities/callback/123-456-7890`

     记录此值，因为该值特定于创建的每个提供商，以后将由 OAuth 2.0 资源提供者使用。
   + 前往您的资源提供商（例如 Google 或 GitHub）创建 OAuth 2.0 应用程序客户端。将服务在调`CreateOauth2CredentialProvider`用资源提供商时发出的回调 URL 作为允许的 OAuth 2.0 回调 URL 提供。
   + 创建 OAuth 2.0 应用程序客户端后，记录分配给应用程序客户端的客户端 ID 和客户端密钥，因为您需要使用这些值更新 OAuth 2.0 凭据提供商。
   + 调用`UpdateOauth2CredentialProvider`并提供资源提供者提供的客户端 ID 和客户端密钥，替换创建凭据提供者时提供的占位符值。

1.  **添加用于调用的代码处理程序 CompleteResourceTokenAuth **-创建 OAuth 2.0 凭证提供商后，在应用程序 URL 处理程序中添加调用 `CompleteResourceTokenAuth` API 的代码和 IAM 权限。调用 `CompleteResourceTokenAuth` API 时，您的应用程序必须出示用于生成工作负载访问令牌的原始入站身份提供商 OAuth 令牌或`user_id`字符串，以代表 OAuth 2.0 授权流程中涉及的用户和代理应用程序。这些信息应从用户浏览器上的活动应用程序会话中获取（通常通过浏览器 cookie 或浏览器本地存储空间），不应从任何远程会话缓存中提取。

   此外，由 I AgentCore dentity 生成的每个授权 URL 均使用其自己的会话 URI 进行唯一标识。此会话 URI 还必须与用户标识符一起显示，以便将会话与目标用户绑定。
**重要**  
在您的应用程序调用 `CompleteResourceTokenAuth` API 之前，您的应用程序必须验证当前用户与您的应用程序的有效会话。这样，您的应用程序就可以将目标用户与授权会话关联起来。此外，如果您的应用程序依赖后端服务，则可以将调用 `CompleteResourceTokenAuth` API 的代码移至您的后端，并让您的应用程序将入站身份提供商 OAuth 令牌转发`user_id`到您的后端。

   示例应用程序代码：

   ```
   def _handle_3lo_callback(self, request: Request) -> JSONResponse:
       session_id = request.query_params.get("session_id")
   
       if not session_id:
           console.print("Missing session_id in OAuth2 3LO callback")
           return JSONResponse(status_code=400, content={"message": "missing session_id query parameter"})
   
       session_details = validate_session_cookies(request.cookies.get('my-application-cookie'))
   
       user_id = None
       if oauth2_config:
           user_id = session_details.get(USER_ID)
   
       if not user_id:
           console.print(f"Missing {USER_ID} in session_details")
           return JSONResponse(status_code=500, content={"message": "Internal Server Error"})
   
       console.print(f"Handling 3LO callback for workload_user_id={user_id} | session_id={session_id}", soft_wrap=True)
   
       region = agent_config.aws.region
       if not region:
           console.print("AWS Region not configured")
           return JSONResponse(status_code=500, content={"message": "Internal Server Error"})
   
       identity_client = IdentityClient(region)
       identity_client.complete_resource_token_auth(
           session_uri=session_id, user_identifier=UserIdIdentifier(user_id=user_id)
       )
   
       return JSONResponse(status_code=200, content={"message": "OAuth2 3LO flow completed successfully"})
   ```

1.  **测试 **-完成设置后，就可以测试集成了。首先调用`GetResourceOauth2Token`，然后在浏览器中转到返回的授权 URL。在 OAuth 2.0 资源提供商处完成授权后，您应该看到浏览器重定向回您的应用程序 URL 并调用 API。`CompleteResourceTokenAuth`应用程序返回有效响应后，您的代理应用程序将能够检索最初为用户请求的 OAuth 2.0 访问令牌。这些令牌可以通过调用 `GetResourceOauth2Token` API 来获取。

## 其他注意事项
<a name="additional-considerations"></a>

在实现 OAuth 2.0 授权 URL 会话绑定时，请记住以下注意事项：
+ 每个授权 URL 及其相应的会话标识符仅在 10 分钟内有效。
+ 为了保护您的应用程序回调端点免受 CSRF 攻击，我们强烈建议您生成一个不透明的状态以包含在对的 API 调用中。`GetResourceOAuth2Token`您的应用程序应该能够解析此值，以确保它能为代理应用程序发起的请求提供服务。