Files
sub2api-cn-relay-manager/deploy/tksea-portal/nginx.sub.tksea.top.conf.example
phamnazage-jpg 4e2ee087fd feat(vNext.4): implement trusted-subject security chain for portal user key self-service
- Add portal_auth.go: Portal user session auth with HMAC-signed cookies
- Add /api/portal/session/{login,logout,state} endpoints
- Update nginx config template: cookie-to-header trusted proxy pattern
- Update frontend: sync CRM session on login/logout
- Add TRUSTED_SUBJECT_DEPLOY_GUIDE.md with remote43 deployment steps
- Update EXECUTION_BOARD.md: mark trusted-subject blocking issue as resolved

This implements the secure chain:
  Browser → Portal → nginx (cookie→header) → CRM (verify proxy secret)

Required remote43 actions:
1. Generate 64-char hex secret
2. Update .env.crm with TRUSTED_* config
3. Update nginx with cookie map and header injection
4. Restart services

Fixes EXECUTION_BOARD.md 2026-06-08 blocking issue
2026-06-09 07:48:03 +08:00

107 lines
3.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# sub.tksea.top portal routing example
#
# 说明:
# - /portal/ 是新的通用多模型接入中心地址
# - /kimi-portal 与 /kimi-portal/ 保留 302 跳转,避免旧链接失效
# - /portal-proxy/ 是页面调用宿主用户态 API 的同域代理
# - /portal-admin-api/ 是页面调用 CRM 管理 API 的同域代理
# - /kimi/ 与 /kimi-v1/ 继续保留,兼容旧的 Kimi 专用客户端配置
#
# 安全注意事项:
# - portal-subject 从 cookie 提取,由后端 /api/portal/session/login 设置 httpOnly cookie
# - CRM 验证 X-CRM-Trusted-Proxy header 确保请求来自受信 nginx
# - 两者必须同时配置才能启用 user-key self-service
# 从 httpOnly cookie 提取 portal subject
map $http_cookie $portal_subject {
default "";
~*crm_session=([^;]+) $1;
}
location = /portal {
return 302 /portal/;
}
location = /portal/admin {
return 302 /portal/admin/;
}
location = /kimi-portal {
return 302 /portal/;
}
# BEGIN sub2api-portal
location /portal/ {
alias /var/www/sub2api-portal/;
index index.html;
try_files $uri $uri/ /portal/index.html;
}
location /portal-proxy/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
location /portal-admin-api/ {
# 必须由受信登录/鉴权层把用户 subject 放进 $portal_subject不能信任浏览器自带 header。
# 同时 CRM 需配置:
# SUB2API_CRM_TRUSTED_SUBJECT_HEADER=X-CRM-Authenticated-Subject
# SUB2API_CRM_TRUSTED_PROXY_SECRET_HEADER=X-CRM-Trusted-Proxy
# SUB2API_CRM_TRUSTED_PROXY_SECRET=<same-secret-as-nginx>
proxy_pass http://127.0.0.1:18190/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 关键:从验证过的 cookie 提取并注入 subject
proxy_set_header X-CRM-Authenticated-Subject $portal_subject;
# 受信代理密钥(必须与 CRM 配置一致)
proxy_set_header X-CRM-Trusted-Proxy "REPLACE_WITH_64_CHAR_HEX_SECRET";
proxy_http_version 1.1;
}
location = /v1/chat/completions {
proxy_pass http://127.0.0.1:18190/v1/chat/completions;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
location /kimi-portal/ {
return 302 /portal/;
}
location /kimi-portal-proxy/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
location /kimi/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
location /kimi-v1/ {
proxy_pass http://127.0.0.1:8080/v1/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
# END sub2api-portal