ALB扩展版支持JWT入站身份认证,在请求转发至后端大模型服务前验证Token有效性,拒绝未授权访问,保护AI服务安全。
方案架构
扩展版ALB实例接收客户端请求,转发规则根据HTTP标头匹配请求。JWT认证组件通过服务扩展关联转发规则,在转发动作前执行:从HTTP请求头中提取JWT Token,使用从远程JWKS服务器获取的公钥对Token进行验证,验证通过时允许请求转发至后端AI服务;验证失败或请求未提供JWT Token时直接返回401响应,阻止请求继续转发。
-
扩展版ALB实例:提供负载均衡和流量转发能力。
-
AI类型服务器组:对接后端大模型服务。
-
HTTPS监听:接收客户端请求。
-
转发规则:根据HTTP标头条件匹配请求并转发。
-
服务扩展:通过JWT认证组件实现入站身份认证和转发控制。
-
JWKS服务器:本文示例使用Nginx模拟,提供公钥信息。
适用范围
-
用户已获取ALB扩展版公测资格。
-
用户已在华北6(乌兰察布)地域创建一个专有网络VPC,分别在可用区A和可用区B创建交换机VSW1和VSW2,且交换机已开通公网SNAT(用于AI服务器组调用公网大模型)。
-
用户已在VSW1或VSW2创建一台ECS(Alibaba Cloud Linux 3.2104系统),且ECS所在安全组已放通VSW1和VSW2的网段IP。
-
用户已开通阿里云百炼并获取了API Key。
-
用户已准备好与自定义域名匹配的服务器证书。非阿里云购买的证书需要上传到阿里云证书服务。
操作步骤
1.创建扩展版ALB实例
-
登录ALB控制台,选择华北6(乌兰察布)地域,单击创建应用型负载均衡。
-
在购买页完成以下配置,单击立即购买。
-
地域:选择华北6(乌兰察布)。
-
实例网络类型:选择公网。
-
VPC和可用区:选择目标VPC,勾选乌兰察布 可用区A和乌兰察布 可用区B后选择对应交换机,并自动分配公网IP。
-
协议版本:选择IPv4。
-
功能版本(实例费):选择扩展版。
-
-
在确认订单页面确认实例配置详情,单击立即开通。
2.创建AI类型服务器组
创建AI类型服务器组,对接阿里云百炼。
-
在服务器组控制台,单击创建服务器组,服务器组类型选择AI服务,输入名称如
sgp-ai-qwen,单击创建。 -
在服务器组创建成功对话框单击添加后端服务器。
-
在添加AI服务对话框完成配置,单击确定。
-
大模型供应商:选择阿里云百炼。
-
服务地址:选择大模型供应商后自动填充。
-
API Key:填入阿里云百炼的API Key。
-
3.创建监听
-
在ALB控制台,单击目标实例ID进入实例详情页。在监听页签单击创建监听。
-
在配置监听步骤,选择监听协议为HTTPS,监听端口填写
443,完成后单击下一步。 -
在配置SSL证书步骤,选择与自定义域名匹配的服务器证书,单击下一步。
-
在选择服务器组步骤,依次选择AI服务类型和服务器组
sgp-ai-qwen,完成后单击下一步。此处选择的服务器组将用于监听的默认规则,即在请求未命中其他转发规则时处理请求,用户可根据实际需求进行调整。
-
在配置审核步骤,确认配置并单击提交。
4.部署JWKS服务器
在ECS上部署Nginx,模拟JWKS服务器提供JWT公钥信息。需确保ALB能够通过VPC内网访问到JWKS服务器。
4.1 生成JWT密钥对和Token
使用Python脚本生成符合规范的公钥JSON文件,以及一个用于测试的JWT Token。
-
登录ECS实例,安装必要的Python依赖库。Alibaba Cloud Linux 默认已安装Python3,需补充安装
jwcrypto库:sudo pip3 install --upgrade pip sudo pip3 install jwcrypto -
创建生成脚本
generate_jwt_jwks.py。sudo vim generate_jwt_jwks.py将以下代码复制到文件中:
import json import time import sys # 检查依赖库 try: from jwcrypto import jwk, jwt except ImportError: print("Error: Library 'jwcrypto' is not installed.") print("Please run: pip3 install jwcrypto") sys.exit(1) def main(): print(">>> 开始生成 JWKS 和 JWT...\n") # --- 配置信息 --- KEY_ID = "aliyun-test-kid" # 密钥ID ISSUER = "http://your-nginx-server-ip" # 建议修改为实际 Nginx IP 或域名,也可保持默认 SUBJECT = "test-user-001" # 测试用户标识 # --- 1. 生成 RSA 密钥对 (2048位) --- # 使用 RS256 算法生成密钥 key = jwk.JWK.generate(kty='RSA', size=2048, alg='RS256', use='sig', kid=KEY_ID) # --- 2. 导出公钥并保存为 jwks.json --- # Nginx 需要读取这个文件来验证 Token public_key = key.export_public(as_dict=True) jwks_data = { "keys": [public_key] } jwks_filename = "jwks.json" with open(jwks_filename, "w") as f: json.dump(jwks_data, f, indent=4) print(f"[成功] JWKS 文件已创建: ./{jwks_filename}") print(f" 后续步骤: 请将此文件移动到 Nginx 目录下。") # --- 3. 生成签名 JWT (使用私钥) --- claims = { "sub": SUBJECT, "iss": ISSUER, "name": "Aliyun Doc User", "role": "admin", "iat": int(time.time()), # 有效期设为 100 年,避免测试期间 Token 过期 "exp": int(time.time()) + 3600 * 24 * 365 * 100 } # 创建并签名 Token token = jwt.JWT( header={"alg": "RS256", "kid": KEY_ID, "typ": "JWT"}, claims=claims ) token.make_signed_token(key) print("\n[成功] 测试 JWT 已生成 (有效期 100 年):") print("-" * 60) print(token.serialize()) print("-" * 60) print("操作: 请使用此 Token 进行 API 请求测试。") if __name__ == "__main__": main() -
运行脚本生成文件:
sudo python3 generate_jwt_jwks.py请注意记录脚本输出中生成的 Token 字符串(即
eyJ...开头的长字符串),后续将在验证环节使用。
4.2 安装和配置Nginx
在ECS实例上安装Nginx,并配置托管上一步生成的 jwks.json 文件。
-
安装Nginx:
sudo yum install -y nginx sudo systemctl start nginx sudo systemctl enable nginx -
准备存放目录并将生成的公钥JSON文件移动到该目录:
# 创建存放目录 sudo mkdir -p /usr/share/nginx/html/auth # 移动 jwks.json 文件 sudo cp jwks.json /usr/share/nginx/html/auth/jwks.json # 赋予读取权限 sudo chmod 644 /usr/share/nginx/html/auth/jwks.json -
在
/etc/nginx/default.d/目录下创建配置文件jwks.conf:sudo vim /etc/nginx/default.d/jwks.conf填入以下配置:
location /auth/v1 { # 禁用缓存,确保客户端总是获取最新的公钥配置 add_header Cache-Control "no-store, no-cache, must-revalidate"; # 设置正确的响应类型 default_type application/json; # 使用 alias 直接指向文件 alias /usr/share/nginx/html/auth/jwks.json; } -
验证Nginx配置并重新加载:
sudo nginx -t sudo systemctl reload nginx -
测试JWKS服务器是否正常返回:
curl http://localhost:port/auth/v1应返回包含
RSA算法(alg: RS256)公钥信息的 JSON 数据,证明 JWKS 服务部署成功。 -
记录ECS实例的私网IP地址,后续用于配置服务扩展。
5.创建服务扩展
创建服务扩展并添加JWT认证组件,配置远程JWKS服务器地址和JWT Token提取方式。
-
在服务扩展控制台,单击创建服务扩展。在服务扩展配置区域,输入服务扩展名称如
jwt-auth-extension。 -
扩展类型默认选择插件,组件名称下拉选择JWT认证。完成以下配置,单击创建。
-
远程服务:填写JWKS服务器地址,格式为
http://<ECS私网IP>:<端口>/auth/v1。例如http://172.16.11.132:80/auth/v1。 -
缓存时间:JWKS公钥缓存时间,使用默认值300秒。
-
JWKS Token配置:
-
类型:选择按HTTP标头。
-
Key:使用默认值
Authorization。 -
Value前缀:使用默认值
Bearer。
-
-
超时时间(毫秒)和处理策略:保持默认值
1000和终止,用户可按需调整。
-
6.配置转发规则
在监听上创建转发规则,添加HTTP标头条件并关联服务扩展。
-
在ALB控制台,单击目标实例ID进入实例详情页。切换到监听页签后,单击目标监听ID进入监听详情页,再切换到转发规则页签。
-
单击插入新规则,完成以下配置后单击确定。
-
转发条件:选择HTTP标头,键是
k,值是v。k: v仅作示例,用于生产时用户可按需配置HTTP标头键值对,或使用其他类型的转发条件。 -
服务扩展(可选):默认使用已有服务扩展,下拉选择
jwt-auth-extension。 -
转发动作:选择转发至AI服务服务器组
sgp-ai-qwen。
-
转发规则创建后,包含HTTP标头k: v的请求会命中该规则,服务扩展从HTTP请求头Authorization中提取JWT Token,并从远程JWKS服务器获取公钥进行验证,验证通过后转发至服务器组sgp-ai-qwen。
7.设置域名解析
将自有域名通过CNAME解析指向ALB实例的DNS名称,客户端通过自有域名访问ALB。
本文以阿里云云解析DNS为例,对于非阿里云注册域名,需先将域名添加到云解析控制台。
8.验证测试
使用curl命令发送请求验证JWT认证功能,请求需满足以下条件:
-
包含转发规则匹配标头
k: v:用于匹配关联了服务扩展的转发规则。 -
符合OpenAI兼容协议:请求路径为
/v1/completions、/v1/chat/completions或/v1/embeddings且整体格式符合规范。
以下测试命令中的域名ai.example.com为示例域名,实际测试时请替换为步骤七中配置的真实域名,需确保域名解析已生效。
请求携带正确的JWT Token
即请求包含Authorization: Bearer <token>头字段,其中<token>为步骤4.1中生成的JWT Token。
# 将下方的 <Token字符串> 替换为步骤 4.1 脚本输出的实际内容
token="<Token字符串>"
curl -v \
-H "k: v" \
-H "Authorization: Bearer $token" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-turbo",
"messages": [
{
"role": "user",
"content": "你是谁"
}
]
}' \
https://ai.example.com/v1/chat/completions
请求成功时,返回HTTP 200状态码和AI服务响应:
{
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "我是千问,是阿里巴巴集团旗下的通义实验室自主研发的超大规模语言模型。我能够回答问题、创作文字、逻辑推理、编程等多种任务。你可以问我任何问题,我会尽我所能提供帮助。",
"role": "assistant"
}
}
],
"created": 1767613123,
"id": "chatcmpl-01fb9300-df1d-98d1-9f5d-874fddebf13f",
"model": "qwen-turbo",
"object": "chat.completion",
"usage": {
"completion_tokens": 47,
"prompt_tokens": 14,
"prompt_tokens_details": {
"cached_tokens": 0
},
"total_tokens": 61
}
}
请求携带错误的JWT Token或请求不携带JWT Token
请求携带错误的JWT Token
即请求包含Authorization: Bearer <token>头字段,但其中<token>非正确的JWT Token。
token="wrong-jwt-token"
curl -v \
-H "k: v" \
-H "Authorization: Bearer $token" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-turbo",
"messages": [
{
"role": "user",
"content": "你是谁"
}
]
}' \
https://ai.example.com/v1/chat/completions
请求失败时,返回HTTP 401状态码,响应体包含认证失败原因。
HTTP响应头:
HTTP/2 401
www-authenticate: Bearer realm="https://ai.example.com/v1/chat/completions", error="invalid_token"
content-length: 79
content-type: text/plain
vary: Accept-Encoding
date: Wed, 21 Jan 2026 06:57:46 GMT
HTTP响应体(示例):
Jwt verification fails
请求不携带JWT Token
即请求不包含Authorization: Bearer <token>头字段。
curl -v \
-H "k: v" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-turbo",
"messages": [
{
"role": "user",
"content": "你是谁"
}
]
}' \
https://ai.example.com/v1/chat/completions
请求失败时,返回HTTP 401状态码,响应体提示找不到JWT Token。
HTTP响应头:
HTTP/2 401
www-authenticate: Bearer realm="https://ai.example.com/v1/chat/completions"
content-length: 14
content-type: text/plain
date: Wed, 21 Jan 2026 07:00:10 GMT
HTTP响应体:
Jwt is missing
更多信息
计费说明
ALB扩展版支持的地域
区域 | 地域 | 可用区 |
中国 | 华北6(乌兰察布) | 可用区A、可用区B、可用区C |
华东1(杭州) | 可用区J、可用区K | |
亚太 | 新加坡 | 可用区A、可用区B、可用区C |
欧洲与美洲 | 德国(法兰克福) | 可用区A、可用区B |
使用建议
-
认证方案升级:本文采用Nginx模拟JWKS服务器,并以固定token进行认证。实际生产中建议部署标准身份认证服务(IdP)提供标准的 JWKS 接口,统一接管密钥轮转与 Token 签发,实现更高的安全性。
-
高可用部署:认证服务应采用多可用区或集群部署,避免因单点故障导致全链路鉴权失败或业务中断。
常见问题
JWT认证失败,返回Jwks remote fetch is failed
说明ALB无法从远程JWKS服务器获取公钥用于认证。可遵循以下思路进行排查:
-
确认服务扩展中配置的远程服务URL正确,且使用ECS实例的私网IP地址。
-
确认ALB实例与ECS实例在同一VPC内,网络互通。
-
确认ECS实例所在安全组及其系统防火墙已放行VSW1、VSW2网段对Nginx服务端口的访问。
-
确认JWKS服务器正常运行,可通过
curl命令在ECS实例本地进行测试。
已配置JWT认证,请求不带token却可以成功
-
确认转发条件与实际请求匹配且转发规则具备足够高的优先级,确保需要进行认证的请求能命中转发规则。
-
确认服务扩展正确添加了JWT认证组件且已关联转发规则。