ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Apereo CAS OIDC Discovery 完整指南:一个 issuer 如何撑起全部端点

Apereo CAS OIDC Discovery 完整指南:一个 issuer 如何撑起全部端点

Apereo CAS OIDC Discovery 完整指南:一个 issuer 如何撑起全部端点

【免费下载链接】casApereo CAS - Identity & Single Sign On for all earthlings and beyond.项目地址: https://gitcode.com/gh_mirrors/ca/cas

你手里只有一个地址:https://sso.example.org/cas/oidc。这是 Apereo CAS 的 OIDC 服务里,认证提供方的"门牌号"(issuer)。客户端要发起登录,却不该把授权、取令牌、校验公钥……十来个端点逐个硬编码进代码。OIDC Discovery 就是干这件事的:客户端只拿着 issuer,就能自动发现其余所有端点和能力。它本质是一份服务注册表,把"CAS 能做什么、去哪调用"以机器可读的方式公开。

先看效果:一条 curl 拿到全部端点

在默认上下文路径/cas下,Discovery 端点长这样:

curl -s https://sso.example.org/cas/oidc/.well-known/openid-configuration

返回是一段 JSON,节选如下:

{ "issuer": "https://sso.example.org/cas/oidc", "authorization_endpoint": "https://sso.example.org/cas/oidc/oidcAuthorize", "token_endpoint": "https://sso.example.org/cas/oidc/oidcAccessToken", "userinfo_endpoint": "https://sso.example.org/cas/oidc/oidcProfile", "jwks_uri": "https://sso.example.org/cas/oidc/jwks", "scopes_supported": ["openid", "profile", "email", "offline_access"] }

客户端拿到这份 JSON,后续所有请求的地址就齐了——它甚至不需要你告诉它每个端点具体在哪。

读懂这份 JSON:端点、能力与算法

元数据看似冗长,其实是围绕三个问题展开的。

端点在哪。所有 URL 都由issuer拼上一段固定路径得到,issuer就是整份 JSON 的根。CAS 一共暴露四个 well-known 入口,前两个返回完全相同的元数据,只是入口不同:

路由(以 /cas 为例)作用
/cas/oidc/.well-known兼容早期约定的裸端点
/cas/oidc/.well-known/openid-configuration标准 OIDC Discovery
/cas/oidc/.well-known/oauth-authorization-serverRFC 8414 风格元数据,输出同上
/cas/oidc/.well-known/webfingerWebFinger 反查入口,见后文

端点规则一致:授权{issuer}/oidcAuthorize、令牌{issuer}/oidcAccessToken、用户信息{issuer}/oidcProfile、单点登出{issuer}/oidcLogout、公钥{issuer}/jwks,另有自省/introspect、吊销/revoke、动态注册/register、PAR 推送/oidcPushAuthorize、CIBA 后信道/oidcCiba。要特别记住的一点:jwks_uri永远指向{issuer}/jwks,客户端凭它取校验令牌签名用的公钥。

支持什么能力。这里是"协议菜单"。scopes_supported声明能申请的 scope(默认含openid、profile、email、offline_access等),claims_supported列出可返回的用户声明,grant_types_supported与response_types_supported声明支持的授权模式,client_registration_types_supported固定为["automatic"],表示支持自动注册客户端。

用什么算法签。ID Token、UserInfo、自省响应各自带一组..._signing_alg_values_supported和加密算法清单,默认以 RS / ES 系列为主;PKCE 的code_challenge_methods_supported支持plain与S256。

先说结论:issuer 校验是一道硬闸。请求的 Host 与 CAS 配置的 issuer 对不上时,端点直接返回 404,不吐出任何元数据。这不是文档里的小字,而是防探测的实打实行为。

改配置:三类属性,按需动手

Discovery 的全部能力挂在cas.authn.oidc.discovery下,对应配置模型OidcDiscoveryProperties。按读者最常改的频率分三类讲。

开关类(布尔)控制某项扩展开不开。claims-parameter-supported、request-parameter-supported默认都是true;require-pushed-authorization-requests默认false,开启后强制所有授权请求走 PAR;tls-client-certificate-bound-access-tokens默认false,做 mTLS 绑定访问令牌时才置true。这类项默认值贴近生产,没有特殊需求可以不动。

列表类决定"菜单"上有哪些条目。最常改的是scopes、claims、response-types-supported、response-modes-supported、prompt-values-supported、grant-types-supported。默认值已经很完整,只有想收窄对外暴露范围时,才需要显式列出。

算法类全是字符串列表,声明签名 / 加密的alg与编码enc白名单。ID Token 签名默认含RS256、ES256等十余种,加密覆盖 RSA-OAEP、A128GCM 系列。除非合规审计要求收紧,默认即可。

完整清单见OidcDiscoveryProperties。这里给一份典型的"收窄"示例:

cas: authn: oidc: issuer: https://sso.example.org/cas/oidc discovery: scopes: openid,profile,email,offline_access claims: sub,name,email,email_verified,preferred_username response-types-supported: code,id_token id-token-signing-alg-values-supported: RS256,RS384,ES256 prompt-values-supported: none,login,consent

改完这些属性,重启 CAS 或刷新配置即生效,无需动任何代码。

一个不用配的例外:acr_values_supported

acr_values_supported(认证上下文类引用)在配置模型里默认是空列表,但 CAS 会自动替你把名字补齐。

打个比方:它像物业自动盘点在场的所有保安——你启用了几种 MFA(Google Authenticator、Duo、WebAuthn、YubiKey……),CAS 就把每个MultifactorAuthenticationProvider的id收进这份清单,直接写进 Discovery 元数据。你不用挨个报名字,启用了什么,它就自动"在场"。

只有当你想手工控制暴露哪些 ACR 值时,才需要显式配置cas.authn.oidc.discovery.acr-values-supported覆盖这个自动行为。

幕后:配置如何变成那段 JSON

链路很短。OidcServerDiscoverySettingsFactory读取casProperties.getAuthn().getOidc().getDiscovery(),把每个配置值拷进一个OidcServerDiscoverySettings对象,同时从OidcIssuerService解析出 issuer。接着OidcWellKnownEndpointController接到请求先做 issuer 校验,通过后取到这个组装好的对象,按 JSON 原样返回。所以"配置 → 对象 → 响应"是一条直线:改配置,就是改输出。

WebFinger:从账号反查你的 Provider

除了标准 Discovery,CAS 还实现了 WebFinger,定位是"给一个账号,反查它的 Provider 是谁"。

  • 端点:/{context-path}/oidc/.well-known/webfinger
  • resource(必填):要查的账号标识,典型形如acct:casuser@sso.example.org
  • rel(可选):关系类型,OIDC 标准值http://openid.net/specs/connect/1.0/issuer

响应媒体类型是application/jrd+json,里面是指向 CAS issuer 的链接,客户端据此拼出完整 Discovery 文档地址。

这里有个坑:resource是必填项,一旦缺失端点直接返回 400 Bad Request;而rel可省略,有无它都返回 200。若压根没配置 WebFinger 服务,则返回 404。

部署后自查清单

部署完成,用下面几条逐一核对 Discovery 是否就位:

  • ✅ 请求openid-configuration返回 200,且$.issuer存在
  • ✅jwks_uri指向{issuer}/jwks,且该地址能取到公钥
  • ✅ 用未注册的域名伪造 Host 访问,应得到 404(不泄漏元数据)
  • ✅ WebFinger 带resource返回 200、缺resource返回 400
  • ✅ 改任一cas.authn.oidc.discovery.*后,响应 JSON 同步变化

【免费下载链接】casApereo CAS - Identity & Single Sign On for all earthlings and beyond.项目地址: https://gitcode.com/gh_mirrors/ca/cas

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进