认证与 SSO:把本系统接进你的账号体系

目前是 JWT Bearer,没有内置的 OIDC/SAML。要做单点登录有两种做法:前置代理换 token,或改源码接 IdP。

学完能做到 员工从企业统一门户点一下就能进系统,不用再输一次账号密码。

开始之前

  • 已了解 API 认证流程
  • 企业有统一身份平台(AD/LDAP/OIDC/企微)或愿意改源码

操作步骤

先看清 token 里有什么

登录返回的 JWT,payload 含 sub(用户 ID)、tenant_id、username,过期时间由 token_expire_minutes 决定。服务端每次请求都会验证:用户存在、is_active、且 user.tenant_id 与 token 里的 tenant_id 一致。所以伪造 token 或跨租户使用都会被拒。

方案 A:前置代理换 token(不改源码)

在你的统一门户自建一个网关:用户在门户登录后,网关用固定的集成账号调 /api/auth/login 拿到 token,再重定向到系统并带上。适合「所有人都用同一个管理员视角看数据」的场景,比如大屏、看板嵌入。不适合需要个人身份留痕的场景。

方案 B:账号同步 + 免密登录(推荐)

用企业目录(AD/LDAP/企微通讯录)同步用户到本系统,密码统一由企业目录管;员工首次通过邀请链接激活后,日常从企业门户点链接进入(门户侧带一次性票据,你的适配层校验后换 token)。身份仍是个人的,操作日志能留痕。

方案 C:改源码接 IdP(私有化)

私有化版本可以直接加 OIDC。改点在 backend/app/api/v1/auth.py 附近新增一个 /api/auth/oidc/callback,用 IdP 返回的 code 换用户信息,再调用现有的 create_access_token 签发本系统 token。不动现有登录逻辑,风险最低。

权限点是第二道闸

认证解决「你是谁」,权限解决「你能看什么」。55 个权限点组成角色,路由 meta.permissions 控制菜单,后端 Depends(get_current_permissions) 控制接口。SSO 接进来的人如果是新账号,记得给角色,否则登录后是一片空白。

退出登录要一起处理

本系统没有 token 黑名单,退出即前端清掉本地 token。做 SSO 时如果门户退出而系统不退,会出现「门户已登出但系统还能用」。建议在门户退出时同步清理系统侧的会话(或把 token 有效期设短)。

代码示例

python方案 C 骨架:加一个 OIDC 回调(私有化改源码)
# backend/app/api/v1/auth.py 追加(示例,非现有代码)
@router.post("/oidc/callback")
def oidc_callback(payload: dict, db: Session = Depends(get_db)):
    # 1) 用 code 向 IdP 换用户信息(此处省略 HTTP 调用细节)
    info = exchange_code_for_userinfo(payload["code"])
    email = info["email"]

    # 2) 找到本系统用户(要求此前已同步或已邀请激活)
    user = db.query(User).filter(User.email == email, User.is_active.is_(True)).first()
    if not user:
        raise HTTPException(status_code=403, detail="账号未开通,请联系管理员")

    # 3) 复用现有签发逻辑,token 结构保持一致
    token = create_access_token(
        {"sub": str(user.id), "tenant_id": user.tenant_id, "username": user.username},
        expires_minutes=token_expire_minutes(False),
    )
    return ok({"access_token": token, "token_type": "bearer"})

示例中的域名、租户编码、密钥请替换成你自己的。生产环境不要把密钥写进前端代码。

容易踩的坑

能不能不改代码就支持 OIDC?
当前没有内置 OIDC/SAML。不改代码只能做方案 A/B(代理换 token 或账号同步 + 门户跳转),真正的协议级 SSO 需要改源码。
SSO 进来的用户没有权限?
自动创建的用户默认没有角色。要么在同步时按部门映射角色(推荐),要么首次登录后由管理员分配。忘了这步会得到「登录成功但什么都看不到」的工单。
集成账号的密码放哪?
放环境变量或密钥管理服务,不要硬编码在代码里、不要提交到 git。集成账号建议不给管理员角色,只给需要的最小权限点。

接着看

还有别的问题?

先看常见问题,或者在系统内提工单,我们会回。