构建您的第一个经过身份验证的代理
本入门教程将引导您使用 Amazon Bedrock Identity 从头开始构建经过 AgentCore 身份验证的完整代理,并将帮助您开始在代理应用程序中实现身份功能。您将学习如何设置开发环境、使用 Cognito 创建身份验证基础架构、将代理部署到 AgentCore Runtime 以及测试完整的身份验证工作流程。
在本教程结束时,您将拥有一个完全部署的代理,该代理可以通过 OAuth2 流程对用户进行身份验证,安全地获取访问令牌,并演示完整的身份管理生命周期。您的代理将使用适当的 IAM 权限在 AgentCore Runtime 上运行,从而创建一个测试实验室环境,您可以在其中演示和测试集成功能。
主题
先决条件
在开始之前,请确保您满足以下条件:
-
具有适当权限的 AWS 账户
-
已安装 Python 3.10+
-
最新的 AWS CLI 并
jq已安装 -
Node.js 已安装 18 个以上(用于 AgentCore CLI)
-
AWS 已配置的凭证和区域 (
aws configure)
本教程要求您拥有 OAuth 2.0 授权服务器。如果您没有,第 1 步将使用 Amazon Cognito 用户池为您创建一个用户池。如果您的 OAuth 2.0 授权服务器配置了客户端 ID、客户端密钥和用户,则可以继续执行步骤 2。该授权服务器将充当资源凭证提供者,代表向代理授予出站 OAuth 2.0 访问令牌的权限。
安装 SDK 和依赖项
为本指南创建一个文件夹,创建 Python 虚拟环境,然后安装 AgentCore SDK 和 AWS Python SDK (boto3)。
mkdir agentcore-identity-quickstart cd agentcore-identity-quickstart python3 -m venv .venv source .venv/bin/activate pip install bedrock-agentcore boto3 strands-agents pyjwt
还要创建包含以下内容的requirements.txt文件。稍后 AgentCore 部署工具将使用它。
bedrock-agentcore boto3 pyjwt strands-agents
步骤 1:创建 Cognito 用户池(可选)
本教程需要 OAuth 2.0 授权服务器。如果您没有可供测试的 Amazon Cognito 实例,或者您想将测试与授权服务器分开,则此脚本将使用您的 AWS 证书设置一个 Amazon Cognito 实例,供您用作授权服务器。该脚本将创建:
-
一个 Cognito 用户池
-
一个 OAuth 2.0 客户端,以及该用户池的客户端密钥
-
该 Cognito 用户池中的测试用户和密码
删除 Cognito 用户池 AgentCoreIdentityQuickStartPool 将同时删除关联的 client_id 和用户。
您可以选择将此脚本另存为 create_cognito.sh 并从命令行执行,也可以将该脚本粘贴到命令行中。
#!/bin/bash REGION=$(aws configure get region) # Create user pool USER_POOL_ID=$(aws cognito-idp create-user-pool \ --pool-name AgentCoreIdentityQuickStartPool \ --query 'UserPool.Id' \ --no-cli-pager \ --output text) # Create user pool domain DOMAIN_NAME="agentcore-quickstart-$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c 5)" aws cognito-idp create-user-pool-domain \ --domain $DOMAIN_NAME \ --no-cli-pager \ --user-pool-id $USER_POOL_ID > /dev/null # Create user pool client with secret and hosted UI settings CLIENT_RESPONSE=$(aws cognito-idp create-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-name AgentCoreQuickStart \ --generate-secret \ --allowed-o-auth-flows "code" \ --allowed-o-auth-scopes "openid" "profile" "email" \ --allowed-o-auth-flows-user-pool-client \ --supported-identity-providers "COGNITO" \ --query 'UserPoolClient.{ClientId:ClientId,ClientSecret:ClientSecret}' \ --output json) CLIENT_ID=$(echo $CLIENT_RESPONSE | jq -r '.ClientId') CLIENT_SECRET=$(echo $CLIENT_RESPONSE | jq -r '.ClientSecret') # Generate random username and password USERNAME="AgentCoreTestUser$(printf "%04d" $((RANDOM % 10000)))" PASSWORD="$(LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*()_+-=[]{}|;:,.<>?' < /dev/urandom | head -c 16)$(LC_ALL=C tr -dc '0-9' < /dev/urandom | head -c 1)" # Create user with permanent password aws cognito-idp admin-create-user \ --user-pool-id $USER_POOL_ID \ --username $USERNAME \ --output text > /dev/null aws cognito-idp admin-set-user-password \ --user-pool-id $USER_POOL_ID \ --username $USERNAME \ --password $PASSWORD \ --output text > /dev/null \ --permanent # Get region ISSUER_URL="https://cognito-idp.$REGION.amazonaws.com/$USER_POOL_ID/.well-known/openid-configuration" HOSTED_UI_URL="https://$DOMAIN_NAME.auth.$REGION.amazoncognito.com" # Output results echo "User Pool ID: $USER_POOL_ID" echo "Client ID: $CLIENT_ID" echo "Client Secret: $CLIENT_SECRET" echo "Issuer URL: $ISSUER_URL" echo "Hosted UI URL: $HOSTED_UI_URL" echo "Test User: $USERNAME" echo "Test Password: $PASSWORD" echo "" echo "# Copy and paste these exports to set environment variables for later use:" echo "export USER_POOL_ID='$USER_POOL_ID'" echo "export CLIENT_ID='$CLIENT_ID'" echo "export CLIENT_SECRET='$CLIENT_SECRET'" echo "export ISSUER_URL='$ISSUER_URL'" echo "export HOSTED_UI_URL='$HOSTED_UI_URL'" echo "export COGNITO_USERNAME='$USERNAME'" echo "export COGNITO_PASSWORD='$PASSWORD'"
步骤 2:创建凭证提供商
凭据提供程序是您的代理访问外部服务的方式。创建凭证提供商,并使用授权服务器的 OAuth 2.0 客户端对其进行配置。
如果您使用的是自己的授权服务器,请使用授权服务器中的相应值设置环境变量ISSUER_URLCLIENT_ID、和CLIENT_SECRET。如果您使用之前的脚本通过 Cognito 为您创建授权服务器,请将输出中的 EXPORT 语句复制到终端中以设置环境变量。
您的代理代码将使用此凭证提供者来获取代表您的用户执行操作的访问令牌。
例
步骤 2.5:将回传网址添加到您的 OAuth 2.0 授权服务器
为防止未经授权的重定向,请将从您的 OAuth 2.0 授权服务器检索到的回传网址添加CreateOauth2CredentialProvider或添加GetOauth2CredentialProvider到 OAuth 2.0 授权服务器。
如果您使用之前的脚本通过 Cognito 创建授权服务器,请将输出中的 EXPORT 语句复制到终端中以设置环境变量,并使用 OAuth2 凭据提供者回调 URL 更新 Cognito 用户池客户端。
#!/bin/bash aws cognito-idp update-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-id $CLIENT_ID \ --client-name AgentCoreQuickStart \ --allowed-o-auth-flows "code" \ --allowed-o-auth-scopes "openid" "profile" "email" \ --allowed-o-auth-flows-user-pool-client \ --supported-identity-providers "COGNITO" \ --callback-urls "$OAUTH2_CALLBACK_URL"
步骤 3:创建启动 OAuth 2.0 流程的示例代理
在此步骤中,我们将创建一个代理来启动 OAuth 2.0 授权流程,让代币代表用户执行操作。为简单起见,代理不会代表用户实际呼叫外部服务,但会向我们证明其已获得代表测试用户行事的同意。
代理代码
创建一个名为的文件agentcoreidentityquickstart.py,然后保存此代码。
""" AgentCore Identity Outbound Token Agent This agent demonstrates the USER_FEDERATION OAuth 2.0 flow. It handles the OAuth 2.0 user consent flow and inspects the resulting OAuth 2.0 access token. """ from bedrock_agentcore.runtime import BedrockAgentCoreApp from bedrock_agentcore.identity import requires_access_token import asyncio import jwt import logging app = BedrockAgentCoreApp() logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def decode_jwt(token): try: decoded = jwt.decode(token, options={"verify_signature": False}) return decoded except Exception as e: return {"error": f"Error decoding JWT: {str(e)}"} class StreamingQueue: def __init__(self): self.finished = False self.queue = asyncio.Queue() async def put(self, item): await self.queue.put(item) async def finish(self): self.finished = True await self.queue.put(None) async def stream(self): while True: item = await self.queue.get() if item is None and self.finished: break yield item queue = StreamingQueue() async def handle_auth_url(url): await queue.put(f"Authorization URL, please copy to your preferred browser: {url}") @requires_access_token( provider_name="AgentCoreIdentityQuickStartProvider", scopes=["openid"], auth_flow="USER_FEDERATION", on_auth_url=handle_auth_url, # streams authorization URL to client force_authentication=True, callback_url='insert_oauth2_callback_url_for_session_binding', ) async def introspect_with_decorator(*, access_token: str): """Introspect token using decorator""" logger.info("Inside introspect_with_decorator - decorator succeeded") await queue.put({ "message": "Successfully received an access token to act on behalf of your user!", "token_claims": decode_jwt(access_token), "token_length": len(access_token), "token_preview": f"{access_token[:50]}...{access_token[-10:]}" }) await queue.finish() @app.entrypoint async def agent_invocation(payload, context): """Handler that uses only the decorator approach""" logger.info("Agent invocation started") # Start the agent task and immediately begin streaming task = asyncio.create_task(introspect_with_decorator()) # Stream items as they come in async for item in queue.stream(): yield item # Wait for task completion await task if __name__ == "__main__": app.run()
注意
有关处理会话绑定的本地回调服务器实现示例,请参阅 oauth2_callback_server.py
步骤 4:将代理部署到 AgentCore 运行时
我们将在 AgentCore Runtime 上托管此代理。我们可以使用 AgentCore CLI 轻松做到这一点。
在您的终端上安装 AgentCore CLI 并创建一个新项目:
npm install -g @aws/agentcore agentcore create --name IdentityQuickstart --defaults
将您的代理脚本复制到项目的代理目录中,替换默认代理:
cp agentcoreidentityquickstart.py IdentityQuickstart/app/IdentityQuickstart/main.py
还要将您的需求文件复制到代理目录中,以确保部署中包含所有依赖项:
cp requirements.txt IdentityQuickstart/app/IdentityQuickstart/
然后部署你的项目:
cd IdentityQuickstart agentcore deploy
CLI 合成一个 AWS CDK 堆栈并将您的代理部署到运行时。 AgentCore 这大约需要 2-3 分钟。
更新代理的 IAM 政策,使其能够访问令牌库和客户端密钥
AgentCore CLI 会在部署期间创建代理的执行角色,但该角色不会自动包含访问令牌库的权限。您需要附加一个策略以允许代理在运行时检索 OAuth 2.0 令牌。
此脚本从 AWS CLI 中检索您的账户和区域,从 CloudFormation 堆栈中找到代理的执行角色,并附加相应的策略。您可以复制并粘贴此脚本,也可以将其保存到文件中并执行。
#!/bin/bash # Get account and region from AWS CLI AWS_ACCOUNT=$(aws sts get-caller-identity --query Account --output text) REGION=$(aws configure get region) # Get execution role from CloudFormation stack outputs EXECUTION_ROLE=$(aws cloudformation describe-stack-resources \ --stack-name AgentCore-IdentityQuickstart-prod \ --query "StackResources[?ResourceType=='AWS::IAM::Role'].PhysicalResourceId" \ --output text | head -1) echo "Parsed values:" echo "Execution Role: $EXECUTION_ROLE" echo "Account: $AWS_ACCOUNT" echo "Region: $REGION" # Create the policy document with proper variable substitution cat > agentcore-identity-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AccessTokenVault", "Effect": "Allow", "Action": [ "bedrock-agentcore:GetResourceOauth2Token", "secretsmanager:GetSecretValue" ], "Resource": ["arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:workload-identity-directory/default/workload-identity/*", "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:token-vault/default/oauth2credentialprovider/AgentCoreIdentityQuickStartProvider", "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:workload-identity-directory/default", "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:token-vault/default", "arn:aws:secretsmanager:$REGION:$AWS_ACCOUNT:secret:bedrock-agentcore-identity!default/oauth2/AgentCoreIdentityQuickStartProvider*" ] } ] } EOF # Create the policy POLICY_ARN=$(aws iam create-policy \ --policy-name AgentCoreIdentityQuickStartPolicy$(LC_ALL=C tr -dc '0-9' < /dev/urandom | head -c 4) \ --policy-document file://agentcore-identity-policy.json \ --query 'Policy.Arn' \ --output text) # Extract role name from ARN and attach policy ROLE_NAME=$(echo $EXECUTION_ROLE | awk -F'/' '{print $NF}') aws iam attach-role-policy \ --role-name $ROLE_NAME \ --policy-arn $POLICY_ARN echo "Policy created and attached: $POLICY_ARN" # Cleanup rm agentcore-identity-policy.json
步骤 5:调用代理
现在一切都设置好了,你可以调用代理了。在本演示中,我们将使用agentcore invoke命令和我们的 IAM 证书。使用 IAM 身份验证时,我们需要传递--user-id和--session-id参数。
agentcore invoke "TestPayload" --runtime IdentityQuickstart --user-id "SampleUserID" --session-id "ALongThirtyThreeCharacterMinimumSessionIdYouCanChangeThisAsYouNeed"
然后,代理将返回您的agentcore invoke命令的 URL。将该 URL 复制并粘贴到您的首选浏览器中,然后您将被重定向到授权服务器的登录页面。--user-id参数是您向 Ident AgentCore ity 提供的用户 ID。--session-id参数是会话 ID,其长度必须至少为 33 个字符。
重要
该--user-id参数使用 GetWorkloadAccessTokenForUserId API 路径,该路径将 userID 视为不透明的字符串,而无需根据经过身份验证的最终用户身份进行验证。这适用于您没有 IdP 令牌可用的快速入门和开发场景。对于使用 JWT 标识最终用户的生产部署,请改用 JWT-based 身份验证路径 (GetWorkloadAccessTokenForJWT),该路径可以验证令牌的颁发者、签名和到期时间。有关更多信息,请参阅获取工作负载访问令牌。
当浏览器出现提示时,在授权服务器上输入用户的用户名和密码,或者使用您配置的首选身份验证方法。如果您使用步骤 1 中的脚本创建 Cognito 实例,则可以从终端历史记录中检索该实例。
您的浏览器应重定向到您配置的 OAuth2 回调 URL,该网址处理会话绑定流程。确保您的 OAuth2 回调服务器提供明确的成功和错误响应,以指示授权状态。
注意
如果您在未完成授权的情况下中断了调用,则可能需要使用新的会话 ID(--session-id参数)请求新的 URL。
调试
如果您遇到任何错误或意外行为,Amazon CloudWatch 日志中会捕获代理的输出。运行agentcore deploy后会提供日志尾随命令。
清理
完成后,运行agentcore remove all然后agentcore deploy从项目目录中删除已部署的 Runt AgentCore ime 资源。然后删除 Amazon Cognito 用户池,分离并删除您创建的 IAM 策略,然后删除该凭证提供商。
安全最佳实践
处理身份信息时:
-
切勿在代理代码中对凭据进行硬编码
-
使用环境变量或 Amazon SageMaker AI 获取敏感信息
-
配置 IAM 权限时应用最低权限原则
-
定期轮换外部服务的凭证
-
审核访问日志以监控代理活动
-
针对身份验证失败@@ 实施正确的错误处理