单点登录系统实现方法详解(详解多子系统一次登录的架构方案)

实现 SSO 的关键不是让每个系统各管登录,而是抽出独立的认证中心(IdP),由它颁发可验证的令牌,各子系统(SP)只负责校验令牌、不再存密码。基于 OIDC + OAuth2.0 的授权码流程,用户登录一次后,访问任何接入的系统都凭同一令牌免登进入。下文给出角色划分、标准流程与可直接落地的令牌签发代码。

一、SSO 的三个核心角色

SSO 的本质是”在多个独立系统间共享认证状态”。无论用哪种协议,架构都围绕中央认证与跨系统会话共享展开。

角色 职责 示例
IdP 认证中心 校验身份、签发令牌、管理全局会话 Keycloak、Auth0、自建
SP 业务系统 校验令牌、创建本地会话,不存密码 OA、订单、支付
User 用户 在 IdP 登录一次,访问全部 SP 企业员工、终端用户

对于现代 Web 与 API,OAuth2.0 + OIDC 是首选:OAuth2.0 管授权,OIDC 在之上补身份层,开箱即得标准化登录。微服务架构里把 IdP、API 网关、各微服务分成三层,网关做统一令牌校验,下游服务再做精细授权。

二、标准登录流程(授权码模式)

用户首次访问 SP1,未登录即被重定向到 IdP;IdP 校验凭证后签发全局令牌并写全局会话 Cookie;SP1 校验令牌后建本地会话。之后再访问 SP2,IdP 发现全局会话有效,直接发针对 SP2 的令牌,用户免登进入。

  1. 用户访问 SP,SP 检测未登录,302 重定向到 IdP 的 /authorize;
  2. 用户在 IdP 输入凭证,IdP 校验通过,生成授权码 code 并重定向回 SP 的回调地址;
  3. SP 后端用 code 向 IdP 的 /token 换取 Access Token 与 ID Token(JWT);
  4. SP 验证 ID Token 签名与 aud / iss / exp,提取用户身份,建立本地会话;
  5. 用户访问其他 SP 时重复 1–4,因全局会话已存在,不再要求输入密码。

公共客户端(SPA、移动端)应使用授权码 + PKCE,避免授权码被拦截;服务端到服务端调用用 RFC 8693 的令牌交换或每次短生命令牌,维持最小权限。

2.1 令牌签发示例(Python)

用 PyJWT 签发和验证 ID Token:

import jwt, time, uuid

SECRET = "your-rsa-or-hmac-secret"  # 生产用非对称密钥,私钥签名

def issue_id_token(user_id: str, role: str) -> str:
    now = int(time.time)
    payload = {
        "iss": "https://idp.example.com",   # 签发方
        "sub": user_id,                       # 用户标识
        "aud": "order-service",               # 受众 SP
        "role": role,
        "iat": now,
        "exp": now + 3600,                     # 1 小时过期
        "jti": str(uuid.uuid4),             # 防重放唯一 ID
    }
    return jwt.encode(payload, SECRET, algorithm="HS256")

def verify_id_token(token: str, audience: str) -> dict:
    return jwt.decode(token, SECRET, algorithms=["HS256"], audience=audience)

Access Token 设为分钟级短生命周期,配刷新令牌轮换;前端用 httpOnly Cookie 存刷新令牌,避免长期凭据落浏览器。

三、跨域与跨系统如何打通

同主域(如 oa.company.com、crm.company.com)可用共享 Cookie/Session;前后端分离或跨域场景必须用令牌方案。JWT 经请求头 Authorization: Bearer 携带,不受 Cookie 域名限制。

场景 推荐方案 理由
同主域内部系统 Cookie/Session 共享 配置简单
跨域 / 微服务 JWT(无状态) 易扩展、跨域友好
企业级 / 第三方对接 OIDC + OAuth2.0 标准化、生态强

四、登出要同步

单点登出要求用户在任一 SP 退出时,IdP 销毁全局会话并通知其余 SP 销毁本地会话。OIDC 提供前端频道(iframe 重定向)与后端频道(webhook)两种登出传播;令牌用不透明令牌 + introspection 端点可即时撤销,JWT 则需维护短期黑名单。各 SP 的本地会话也要随全局登出一起清,否则会出现”退出一个系统另一个还在线”的割裂体验。

常见问题(FAQ)

Q1:SSO 和 OAuth2.0 是一回事吗?

不是。SSO 是目标,OAuth2.0 是手段,通常配 OIDC 补身份层。

Q2:JWT 怎么强制登出?

短过期 + 刷新令牌轮换,或用黑名单 / introspection 撤销。

Q3:多个 SP 必须同域名吗?

不必。用 Bearer 令牌跨域,IdP 统一签发即可。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
赵其鑫的头像赵其鑫管理团队

相关推荐

返回顶部