启用配置

简要概述

内置 admin 管理后台由三部分组成,配置缺一不可:

组成路由由哪个配置项开启
KnownAdmin gRPC 服务 + HTTP API/builtin/admin/api/v1/...services.integrations.grpc.admin
前端静态资源托管/adminfrontend.interface.admin
业务数据库(lion)—database

必须配置项

配置项作用缺失后果
services.integrations.grpc.admin: true注册 KnownAdmin gRPC 服务与 /builtin/admin/api/v1 HTTP 路由无 admin API,前端登录接口 404
services.http_addressHTTP gateway 监听地址gateway 不开启,admin API 与前端均无入口
services.security_keyadmin 模块 AES 密钥(16/24/32 字节)DB 中 email、凭证、JWKS 私钥等加密字段无法加解密
database.enable + 连接信息admin 业务数据(用户/角色/凭证等)admin 服务降级:仅静态用户可登录,无用户管理等后台功能
frontend.enable: true前端托管总开关/admin 页面不可访问
frontend.interface.admin.enabled: trueadmin 前端托管开关(默认 false)同上
security.authentication.oidc_provider登录必需(见下文)登录一律 400 access token client_id is required
security.authentication.http_users本地静态用户(可选,DB 用户亦可登录)只能使用 DB 用户登录
security.authorization.allowed_roles + 用户的 rolesadmin API 访问授权登录成功后所有 admin API 返回 403

frontend.interface.admin.embedded: true 使用二进制内嵌的前端资源(推荐本地使用), handle_url 控制挂载路径(默认 /admin)。

services.security_key 在本地可用固定 32 字节字面量;生产环境必须替换为独立生成的 密钥(泄露等价于泄露库内全部加密字段)。

为什么登录依赖 oidc_provider

自令牌签发统一重构(AccessTokenClaims)后,登录签发的 access token 必须携带 client_id 声明,而该值的唯一配置来源是 security.authentication.oidc_provider.config.client_id(CreateAuthLoginRequest 协议本身没有 client_id 字段)。校验发生在用户名/密码验证之前,因此未配置时 无论凭据对错,POST /builtin/admin/api/v1/auth/login 一律返回:

{"error": {"code": 400, "status": "FailedPrecondition",
           "message": "access token client_id is required"}}

本地部署不需要真实的外部 OIDC 服务,将 issuer 指向 admin 内置的 OAuth2 端点即可 完成自举(内置端点提供 discovery 与 jwks,RS256 token 验证由此通过):

security:
  enable: true
  authentication:
    oidc_provider:
      # 指向内置 OAuth2 端点;端口须与 services.http_address 一致
      issuer: http://127.0.0.1:8080/builtin/admin/api/v1/oauth2
      config:
        client_id: example-admin
        supported_signing_algs:
          - RS256   # DB 用户 token(DB 中 JWKS RSA 密钥签发)
          - HS256   # 静态用户 token(口令哈希做 HMAC key)
        # 本地签发的 token 不含 iss/aud 声明,必须跳过这两项校验
        skip_issuer_check: true
        skip_client_id_check: true

三个 skip_* 与 supported_signing_algs 不是可选项:本地签发的 token 不写入 iss/aud 声明,不跳过会被验证层拒绝;HS256 验证分支仅在 supported_signing_algs 包含 HS256 时启用。

本地静态用户与授权

admin API 要求 token 携带 roles 声明,且与 authorization.allowed_roles 有交集 (superadmin 为 admin 包内置的完整权限角色,DB 种子角色 code 与之一致):

    http_users:
      - username: user1
        password: example-password       # 本地明文;服务端按 sha256 口令约定使用
        roles:
          - superadmin

  authorization:
    allowed_roles:
      - superadmin

登录协议约定:CreateAuthLoginRequest.password_hash 传 sha256(明文) 的十六进制 (LOCAL provider);LDAP provider 传 base64(明文)。前端已按此约定处理。

首次部署与初始化

  1. 表结构:服务启动时自动创建/迁移 lion 数据库(db.Schema.Create),无需手工执行。

  2. 种子数据:调用一次幂等的初始化接口,补全内置用户/组/角色/策略与 JWKS RSA 签名密钥(已存在则跳过,可重复调用):

    curl -X POST http://127.0.0.1:8080/builtin/admin/api/v1/database/initialize \
      -H 'Content-Type: application/json' \
      -d '{"password_hash": "<sha256(新口令) 的 64 位十六进制,留空用默认密码>"}'
    

    种子内容包含 bootstrap 用户 admin(初始超级管理员,系统配置成功后建议删除或 禁用)及 superadmin/admin/user/guest 内置角色。

验证

# 登录(静态用户)
PW_HASH=$(printf 'example-password' | shasum -a 256 | cut -d' ' -f1)
TOKEN=$(curl -s -X POST http://127.0.0.1:8080/builtin/admin/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d "{\"username\":\"user1\",\"password_hash\":\"$PW_HASH\"}" \
  | sed -E 's/.*"access_token":"([^"]+)".*/\1/')

# 带 token 访问 admin API(应返回用户列表而非 401/403)
curl -s http://127.0.0.1:8080/builtin/admin/api/v1/users?page_size=1 \
  -H "Authorization: Bearer $TOKEN"

常见故障对照

现象根因处理
登录 400 access token client_id is required未配置 oidc_provider.config.client_id按上文补全 oidc_provider 段
登录成功但 admin API 403 user has no role assignments静态用户未配 roles 或缺 authorization.allowed_roles两处都补 superadmin
admin API 401(token 校验失败)supported_signing_algs 缺 HS256,或未跳过 iss/aud 校验对照上文 oidc_provider.config 三项
日志反复 OIDC provider discovery failed; retryingissuer 端口与 http_address 不一致,或服务尚未监听启动初期重试属正常;持续失败则核对 issuer
/admin 404frontend.enable 或 frontend.interface.admin.enabled 未开两级开关都设为 true

生产环境注意事项

  • services.security_key、静态用户口令、bootstrap admin 用户默认口令都必须替换; bootstrap 用户完成初始化后建议删除或禁用(种子描述中亦有提示)。
  • skip_issuer_check/skip_client_id_check 是本地自举的妥协;若接入真实外部 OIDC provider,应按实际 issuer/client_id 恢复校验。