本教程介绍如何将阿里云RDS AI助手页面以iframe形式嵌入自建Web应用。该方案通过RAM、STS(Security Token Service)临时凭证和阿里云登录服务,生成一个免登录访问链接,实现在自有系统中无缝集成和使用RDS AI助手的功能。
背景信息
在企业内部的数据库管理平台或运维系统中,您可能希望集成RDS AI助手的能力,以提供智能诊断、SQL优化等功能。通过将RDS AI助手页面嵌入您的自建Web应用,可以实现以下目标:
-
提升用户体验: 用户无需在您的应用和阿里云控制台之间频繁切换和登录,实现单点登录(SSO)的无缝体验。
-
精细化权限管控: 可通过RAM角色为不同用户授予不同的访问权限,例如为开发人员授予只读权限,为DBA授予完整管理权限,确保操作安全可控。
访问流程
整体访问流程如下图所示,核心步骤包括获取临时凭证、换取登录令牌、构造并访问最终的免登录URL。
-
用户登录自建Web平台。
-
自建Web平台的后端服务调用STS的
AssumeRole接口,请求一个临时身份凭证。 -
STS服务返回包含临时AccessKey(AK)、Secret和Token的凭证。
-
后端服务使用该临时凭证,调用阿里云登录服务的
GetSigninToken接口。 -
登录服务返回一个用于单点登录的
SigninToken。 -
后端服务使用此
SigninToken和目标RDS AI助手页面的URL,构造一个最终的免登录访问链接,并返回给前端。前端即可通过此链接在iframe中或新标签页中打开RDS AI助手。
创建RAM用户、RAM角色并授权
创建RAM用户并授权
创建一个专用于调用STS服务的RAM用户,并授予其扮演角色的权限。
1. 创建后端专用RAM用户
-
登录RAM控制台。
-
在左侧导航栏,选择身份管理 > 用户。
-
在用户页面,单击创建用户。
-
在创建用户页面,配置用户名称等基本信息,在访问配置区域,选中使用永久AccessKey访问,便于后端服务通过RAM用户的AccessKeyId和AccessKeySecret调用STS。
-
在创建结果页面,查看并保存RAM用户的AccessKeyId和AccessKeySecret。具体操作请参见创建AccessKey。
-
务必在创建结果页面保存AccessKeyId和AccessKeySecret,页面关闭后无法再次查询。请妥善保管该凭证,后续后端脚本将使用它们调用STS服务。
-
AccessKeySecret只能保存在自建Web后端运行环境或密钥管理系统中,不要写入前端代码、Git仓库、文档截图、日志或工单。
-
不建议使用主账号AccessKey做集成验证。主账号权限过大,无法验证真实客户最常见的RAM授权边界问题。
2. 为RAM用户授权AssumeRole
后端专用RAM用户需要具备扮演目标RAM角色的权限,您需要创建一个自定义权限策略并授权给该RAM用户。
-
在左侧导航栏,选择权限管理 > 权限策略。
-
在权限策略页面,单击创建权限策略。
-
在创建权限策略页面,选择脚本编辑页签,输入以下JSON策略内容:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "acs:ram::<account_id>:role/<ram_role_name>"
}
]
}
替换规则:
-
<account_id>:阿里云主账号ID。 -
<ram_role_name>:后续创建的RAM角色名称,例如rdscopilot-console。
创建完成后,将该策略授权给后端专用RAM用户:
-
在权限策略列表中,单击刚创建的策略名称。
-
在策略详情页面,单击授权管理页签,然后单击新增授权。
-
在新增授权面板,资源范围选择账号级别。
-
在授权主体区域,勾选上一步创建的后端专用RAM用户。
-
单击确认新增授权。具体操作请参见管理RAM用户的权限。
创建RAM角色并授权
创建一个RAM角色,您的Web应用将通过AssumeRole扮演该角色来访问RDS AI助手。最终用户访问页面时,将拥有此角色所具备的权限。
1. 创建可信实体为阿里云账号的RAM角色
在RAM控制台创建RAM角色,操作步骤如下:
-
在左侧导航栏,选择身份管理 > 角色。
-
在角色页面,单击创建角色。
-
在创建角色页面,按下表选择关键配置,输入角色名称,单击确定。具体操作请参见创建可信实体为阿里云服务的RAM角色。
|
配置项 |
建议值 |
|
可信主体类型 |
阿里云账号 |
|
信任主体名称 |
当前云账号,或允许调用STS的账号 |
|
角色名称 |
例如 |
2. 配置RAM角色信任策略
推荐将RAM角色信任策略收敛到上一步创建的后端专用RAM用户,操作步骤如下:
-
在角色列表中,单击刚创建的RAM角色名称。
-
在角色详情页面,单击信任策略页签,然后单击编辑信任策略。
-
选择脚本编辑页签,将策略内容修改为以下示例:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"RAM": "acs:ram::<account_id>:user/<ram_user_name>"
},
"Action": "sts:AssumeRole"
}
]
}
替换规则:
-
<account_id>:RAM用户所在阿里云主账号ID。 -
<ram_user_name>:上一步创建的RAM用户名称。
检查信任策略时,请重点确认以下内容:
|
检查项 |
正确结果 |
|
|
|
|
|
包含 |
|
|
指向后端专用RAM用户ARN |
如果AssumeRole报AccessDenied,请优先检查以下两项:
-
RAM用户是否有
sts:AssumeRole到目标RoleArn的权限。 -
RAM角色信任策略是否允许该RAM用户扮演。
3. 为RAM角色授权RDS和RDS AI助手权限
为创建的RAM角色授予访问RDS和RDS AI助手的权限,操作步骤如下:
-
在角色详情页面,单击权限管理页签,然后单击新增授权。
-
在新增授权面板,资源范围选择账号级别。
-
在权限策略区域,搜索并勾选目标权限策略,单击确认新增授权。具体操作请参见管理RAM角色的权限。根据业务需求,选择添加以下权限策略:
-
RDS基础权限:
-
AliyunRDSFullAccess:RDS的完整管理权限。 -
AliyunRDSReadOnlyAccess:RDS的只读访问权限。
-
-
RDS AI助手权限:
-
AliyunRDSAIFullAccess:RDS AI助手的完整管理权限。 -
AliyunRDSCopilotReadOnlyAccess:RDS AI助手的只读访问权限。
-
为了确保能正常访问RDS AI助手功能,建议至少添加AliyunRDSReadOnlyAccess(RDS基础只读权限)和AliyunRDSCopilotReadOnlyAccess(RDS AI助手只读权限)。如果用户需要在页面内执行管理类操作,可根据业务需要替换为AliyunRDSFullAccess和AliyunRDSAIFullAccess;如果只需要查看实例、咨询、诊断和只读分析能力,建议优先使用只读策略。
4. 获取RAM角色ARN
-
使用RAM管理员登录RAM控制台。
-
在左侧导航栏,选择身份管理 > 角色。
-
在角色页面,单击目标RAM角色名称。
-
在RAM角色详情页面的基本信息区域,复制ARN信息。
格式示例:
acs:ram::13427***:role/rdscopilot-console
该ARN需要和RAM用户的sts:AssumeRole授权策略中的Resource保持一致。
配置开发环境
安装依赖
pip install Flask==2.3.0 requests==2.31.0 aliyun-python-sdk-core==2.13.36 aliyun-python-sdk-sts==3.1.0
配置环境变量
export ALIYUN_ACCOUNT_ID="your-account-id" #阿里云账号ID
export ALIYUN_ACCESS_KEY_ID="your-access-key-id" #RAM用户的AccessKeyId
export ALIYUN_ACCESS_KEY_SECRET="your-access-key-secret" #RAM用户的AccessKeySecret
export ALIYUN_RAM_ROLE="your-ram-role-name" #RAM角色名称
完整示例代码与核心逻辑分析
完整示例代码
以下提供一个基于Python Flask框架的完整后端服务和前端页面示例。
核心逻辑分析
获取临时AccessKey和Token
在您的Web应用后端服务中,使用步骤一中RAM用户的AccessKey,调用STS的AssumeRole接口,获取用于访问云服务的临时身份凭证。
以下为Python SDK示例代码:
import json
from aliyunsdkcore.client import AcsClient
from aliyunsdksts.request.v20150401.AssumeRoleRequest import AssumeRoleRequest
# 配置信息
ACCOUNT_ID = os.environ.get("ALIYUN_ACCOUNT_ID")
ACCESS_KEY_ID = os.environ.get("ALIYUN_ACCESS_KEY_ID")
ACCESS_KEY_SECRET = os.environ.get("ALIYUN_ACCESS_KEY_SECRET")
RAM_ROLE = os.environ.get("ALIYUN_RAM_ROLE", "rdscopilot-console")
REGION_ID = "cn-hangzhou"
def assume_role():
"""通过 STS 获取临时凭证"""
client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, REGION_ID)
request = AssumeRoleRequest()
request.set_RoleArn(f"acs:ram::{ACCOUNT_ID}:role/{RAM_ROLE}")
request.set_RoleSessionName("rds-ai-assistant-session")
request.set_DurationSeconds(3600) # Token有效期1小时
response = client.do_action_with_exception(request)
return json.loads(response)["Credentials"]
返回示例:
{
"AccessKeyId": "STS.xxx",
"AccessKeySecret": "xxx",
"SecurityToken": "CAISxxx...",
"Expiration": "2026-01-22T10:00:00Z"
}
获取登录Token
通过上一步STS的AssumeRole接口获取临时AccessKey和Token后,调用登录服务接口获取登录Token。
请求登录服务接口示例:
https://signin.aliyun.com/federation?Action=GetSigninToken
&AccessKeyId=<STS返回的临时AccessKeyId>
&AccessKeySecret=<STS返回的临时AccessKeySecret>
&SecurityToken=<STS返回的安全Token>
&TicketType=mini
-
STS返回的
SecurityToken可能包含+、/等特殊字符,在作为URL参数传递前,必须进行URL编码。 -
若您希望将页面嵌入到
<iframe>中,请求时必须添加&TicketType=mini参数。
Python示例代码:
import requests
from urllib.parse import quote
SIGN_IN_DOMAIN = "https://signin.aliyun.com/federation"
def get_signin_token(access_key_id, access_key_secret, security_token):
"""使用临时凭证获取登录 Token"""
params = {
"Action": "GetSigninToken",
"AccessKeyId": access_key_id,
"AccessKeySecret": access_key_secret,
"SecurityToken": security_token,
"TicketType": "mini"
}
resp = requests.get(SIGN_IN_DOMAIN, params=params)
if resp.status_code == 200:
return resp.json().get("SigninToken")
else:
raise Exception(f"Failed to get SigninToken: {resp.status_code}, {resp.text}")
返回示例:
{
"SigninToken": "xxx-xxx-xxx"
}
生成免登录链接
使用上一步获取的SigninToken和目标RDS AI助手页面的URL,构造最终的免登录链接。
由于SigninToken有效期为3小时,建议在自建Web应用中将链接设置为每次请求时生成新登录Token。
-
获取RDS AI助手控制台页面URL。
地域
域名
中国站
rdsnext4service.console.aliyun.comURL示例:
https://rdsnext4service.console.aliyun.com/rdsCopilotFree/cn-hangzhou?hideTopbar=true&copilotReference -
构造免登录访问链接。
请求格式:
https://signin.aliyun.com/federation?Action=Login &LoginUrl=<登录失效跳转的地址> &SigninToken=<获取到的登录SigninToken> &Destination=<目标RDS AI助手控制台页面链接>Python示例代码:
import requests def get_login_url(signin_token, destination_url): """构造最终的登录跳转 URL""" params = { "Action": "Login", "LoginUrl": "https://signin.aliyun.com/login.htm", "Destination": destination_url, "SigninToken": signin_token } # 使用 requests 构造完整的 URL req = requests.Request('GET', SIGN_IN_DOMAIN, params=params).prepare() return req.url -
访问免登录链接。
将生成的最终URL返回给前端。前端可以在<iframe>的src属性中加载此URL,或通过新标签页打开,即可实现免登录访问RDS AI助手。
服务启动
本地环境启动命令
python app.py
生产环境启动命令
生产环境建议使用gunicorn或uWSGI。
gunicorn -w 4 -b 0.0.0.0:5023 app:app
常见问题
-
Q:嵌入的页面一段时间后无法访问或提示登录,是什么原因?
A:这是因为SigninToken具有时效性(有效期为3小时)。为了获得最佳体验,建议不要在前端缓存生成的免登录URL。应在每次需要加载或刷新嵌入页面时,都由前端实时向后端请求一个新的免登录URL。同时,请检查以下内容:
-
GetSigninToken请求是否包含TicketType=mini。 -
前端是否缓存了旧的federation URL。
-
后端是否错误返回了已打码或不完整的URL。
-
-
Q:页面嵌入后提示“权限不足”或无法看到实例列表,如何解决?
A:可能是RAM角色未配置足够的RDS或RDS AI助手权限。请检查为RAM角色配置的权限。-
确认角色是否已附加
AliyunRDSReadOnlyAccess(或AliyunRDSFullAccess)权限,这是查看RDS实例列表的基础。 -
确认角色是否已附加
AliyunRDSCopilotReadOnlyAccess(或AliyunRDSAIFullAccess)权限,这是使用RDS AI助手功能所必需的。 -
如果使用了自定义权限策略,请确保策略中包含访问RDS实例(例如
rds:Describe*)和RDS AI助手相关操作的权限。
说明这里应检查RAM角色权限,而不是后端RAM用户权限。后端RAM用户只负责调用
AssumeRole。 -
-
Q:调用
AssumeRole报AccessDenied,如何排查?
A:按以下顺序检查:-
RAM用户是否有
sts:AssumeRole权限。 -
RAM用户授权策略中的
Resource是否为目标RAM角色的ARN。 -
RAM角色信任策略中的
Principal.RAM是否指向该RAM用户。 -
是否误创建了“可信实体为阿里云服务”的角色,导致信任策略中只有
Principal.Service。
-
-
Q:调用
GetSigninToken报错或iframe无法加载,如何排查?
A:按以下顺序检查:-
SecurityToken是否作为URL参数正确编码。 -
请求
GetSigninToken时是否包含TicketType=mini。 -
后端是否使用STS返回的临时AK/SK/Token,而不是原始RAM用户AK/SK。
-
Destination是否整体URL编码,避免内部&被federation URL当成外层参数。
-
-
Q:RAM用户和RAM角色的权限应该如何分配?
A:推荐规则如下:权限
授予对象
sts:AssumeRole后端专用RAM用户
AliyunRDSReadOnlyAccess或AliyunRDSFullAccessRDS AI助手访问RAM角色
AliyunRDSCopilotReadOnlyAccess或AliyunRDSAIFullAccessRDS AI助手访问RAM角色
如果授权方向反了,常见表现是:
-
RAM用户有RDS权限,但
AssumeRole失败。 -
RAM角色能被扮演,但页面打开后看不到实例或提示权限不足。
-