OAuth2.0 / OIDC 接入

Passport 内置 OAuth2.0 授权服务器与 OIDC Provider(OP),第三方 Web 应用、SPA、移动端或服务间调用可以通过标准协议接入 VanCone 统一认证,无需使用自定义 Token 体系。SAML2 接入见「SAML2 接入」。

前置条件:注册客户端

接入方需要在 VanCone 管理控制台 「OAuth / OIDC 客户端」 页面注册一个客户端,注册后获得:

  • Client ID:公开标识;
  • Client Secret:仅在创建或「重置密钥」时展示一次,请妥善保存(服务端只保存哈希);
  • 回调地址白名单:精确匹配,不支持通配符;
  • 授权方式(grant types) 与 授权范围(scopes)。

客户端类型:

类型适用场景令牌端点认证
CONFIDENTIAL有后端的 Web 应用client_secret_basic(HTTP Basic)或 client_secret_post
PUBLICSPA / 移动端,无法保密 secretnone,强制 PKCE

服务发现

OIDC 客户端可直接从 discovery 文档获取全部端点:

GET https://vancone.com/.well-known/openid-configuration

关键端点:/oidc/authorize(授权)、/oidc/token(令牌)、/oidc/userinfo、/oidc/jwks(公钥集,ES256)。

授权码流程(authorization_code + PKCE)

浏览器                          接入方后端                Passport
   │ 1. 跳转授权端点               │                        │
   │──────────────────────────────────────────────────────>│
   │      (未登录时先到 Passport 登录页,登录后自动回来)      │
   │ 2. 首次授权展示确认页(consent)                          │
   │ 3. 302 回调地址 ?code=...&state=...                    │
   │<──────────────────────────────────────────────────────│
   │ 4. 交出 code ─────────────────>│ 5. code+secret 换令牌   │
   │                                │───────────────────────>│
   │<─── 返回业务会话 ───────────────│<── access/id/refresh ──│

第 1 步 — 引导用户浏览器访问:

https://vancone.com/oidc/authorize
  ?client_id={clientId}
  &redirect_uri={已注册的回调地址}
  &response_type=code
  &scope=openid profile
  &state={随机防CSRF}
  &code_challenge={S256(verifier)}&code_challenge_method=S256
  &nonce={随机}

第 2 步 — 用户未登录时会被带到 Passport 登录页,登录后自动回到授权流程;首次授权会展示 scope 确认页,同意后 Passport 302 回回调地址并携带 code 与 state。

第 3 步 — 后端用授权码换令牌:

POST /oidc/token
Authorization: Basic base64(clientId:clientSecret)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code={code}
&redirect_uri={与第 1 步完全一致}
&code_verifier={PKCE verifier}

响应:

{
  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "仅 scope 含 offline_access 且客户端允许时返回",
  "id_token": "仅 scope 含 openid 时返回(ES256 JWT)",
  "scope": "openid profile"
}

授权码 10 分钟有效且只能使用一次;PKCE 的 code_verifier 必须与授权请求的 code_challenge 匹配。

令牌说明

令牌形态用途
access_tokenES256 JWT(kid 发布于 /oidc/jwks)调用接入方资源接口;claims 含 sub(用户ID)、aud(client_id)、scope、tid(租户)
id_tokenES256 JWT(OIDC)标识登录用户:sub、nonce、at_hash、name/preferred_username/email/phone(随 scope)
refresh_token不透明随机串换取新令牌对,每次刷新轮换(旧令牌立即失效)

刷新令牌

POST /oidc/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token={refreshToken}&client_id={clientId}
(CONFIDENTIAL 客户端需携带 Basic 认证)

服务间调用(client_credentials)

无用户参与的机器对机器调用,仅 CONFIDENTIAL 客户端可用:

POST /oidc/token
Authorization: Basic base64(clientId:clientSecret)

grant_type=client_credentials&scope={可选的自定义 scope}

签发的 access_token sub 为 client_id,不含用户信息。

用户信息(userinfo)

GET /oidc/userinfo
Authorization: Bearer {access_token}

按 scope 返回 claims:sub(必返)、profile → name/preferred_username、email → email、phone → phone。

令牌自省与吊销

POST /oidc/introspect    # RFC 7662,form 参数 token=...
POST /oidc/revoke        # RFC 7009,吊销后该令牌立即失效

两个端点均需要客户端认证。

退出登录

引导浏览器访问 GET /oidc/logout?post_logout_redirect_uri={可选}:Passport 清除会话 Cookie 后跳转到指定地址(仅允许相对路径或 *.vancone.com)。

安全要求

  • 回调地址白名单精确匹配,请注册完整 URL;
  • PUBLIC 客户端必须使用 PKCE(S256);
  • state 每次授权随机生成用于防 CSRF;nonce 随机生成并在校验 id_token 时核对;
  • Client Secret 泄露时立即在控制台「重置密钥」;
  • 生产环境请通过 HTTPS 访问 Passport(vancone.com 默认为 HTTPS)。