
你的客户端凭什么找到 CAS 的 OIDC 端点Discovery 机制与 cas.authn.oidc.discovery 配置实战【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址: https://gitcode.com/gh_mirrors/ca/cas假设你要把内部 SSO 对接进一个新项目。客户端开发者只拿到一个地址——issuer形如https://sso.example.org/cas/oidc。他凭什么知道授权请求该发到哪、令牌往哪换、公钥又放在哪个地址答案藏在 CAS 的 well-known 端点里拿 issuer 拼上一个约定好的路径服务器就会返回一整份 JSON把所有端点 URL、支持的 scope 与 claim、签名算法清单一次性交代清楚。这就是 Apereo CAS 的 OIDC Discovery——客户端不需要任何硬编码拿到 issuer 就能自发现。本文从一条 curl 命令出发拆清这份 JSON 的来龙去脉再给出几份可直接套用的 YAML 配方。跑通第一个请求以本地默认部署的 CAS 为例issuer 默认值即http://localhost:8080/cas/oidc打开终端敲三行命令# 标准 OIDC Discovery 端点 curl -s http://localhost:8080/cas/oidc/.well-known/openid-configuration # 裸 .well-known 端点输出与上面完全一致 curl -s http://localhost:8080/cas/oidc/.well-known响应是一段紧凑的 JSON用jq挑几个关键字段看效果curl -s http://localhost:8080/cas/oidc/.well-known/openid-configuration \ | jq {issuer, authorization_endpoint, token_endpoint, jwks_uri, scopes_supported}{ issuer: http://localhost:8080/cas/oidc, authorization_endpoint: http://localhost:8080/cas/oidcAuthorize, token_endpoint: http://localhost:8080/cas/oidcAccessToken, jwks_uri: http://localhost:8080/cas/oidc/jwks, scopes_supported: [openid, profile, email, ...] }三个值得留意的点authorization_endpoint、token_endpoint这类字段不在 issuer 之下.../cas/oidc/oidcAuthorize而jwks_uri又在 issuer 之下.../oidc/jwks——所有端点都是 issuer 拼接固定路径段算出来的这一点后面细说。第二个入口是 RFC 8414 风格的oauth-authorization-server输出与openid-configuration完全相同只是 URL 不同。上图描绘了后续真正发生授权交互时的时序——而 Discovery 就是客户端发起这一切之前先读说明书的那一步。核心机制拆解一个请求从进来到出去入口三条 well-known 路由全部 Discovery 流量由support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/controllers/discovery/OidcWellKnownEndpointController.java承载路由常量定义在support/cas-server-support-oidc-core/src/main/java/org/apereo/cas/oidc/OidcConstants.java路由{context}为/cas时的完整形式返回内容{context}/oidc/.well-known标准发现文档兼容早期约定的裸入口{context}/oidc/.well-known/openid-configuration标准发现文档OIDC 规范定义的位置{context}/oidc/.well-known/oauth-authorization-server同一份文档的 RFC 8414 风格入口{context}/oidc/.well-known/webfingerJRD 格式反查文档application/jrdjson前三个路由返回同一个对象webfinger独立处理稍后单说。关卡issuer 校验不匹配就 404控制器在吐任何元数据之前会先走isIssuerValidForEndpoint从请求 URL 中剥掉端点路径段剩下的部分与 CAS 配置的 issuer 比对支持accepted-issuers-pattern正则兜底。比对失败的后果不是 403而是404 Not Found——元数据干脆不泄漏给来路不明的 Host。这也是部署在反向代理后、换域名时最容易踩的坑代理透传的 Host 与配置 issuer 对不上端点就消失了。装配配置如何变成 JSON真正的数据对象是support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/discovery/OidcServerDiscoverySettings.java由OidcServerDiscoverySettingsFactory以单例FactoryBean装配Bean 名oidcServerDiscoverySettingsFactory。装配时做三件事解析 issuer默认取cas.authn.oidc.issuer源码默认http://localhost:8080/cas/oidc定义于OidcCoreProperties多租户场景可被注册服务自身的idTokenIssuer覆盖逐项拷贝cas.authn.oidc.discovery.*配置进对象覆盖默认值动态拼接所有*_endpoint字段每个端点 getter 都是issuer 固定路径段。比如token_endpoint拼oidcAccessTokenend_session_endpoint拼oidcLogoutrevocation_endpoint拼revoke。所以只要 issuer 变了端点字段自动跟随不存在单独配置端点 URL 的旋钮。输出响应里哪些字段真正重要按使用方关心的维度把响应字段分三类看客户端必用写代码时一定会读字段默认值issuer 拼接issuer配置值原样输出authorization_endpoint{issuer}/oidcAuthorizetoken_endpoint{issuer}/oidcAccessTokenjwks_uri{issuer}/jwksuserinfo_endpoint{issuer}/oidcProfileend_session_endpoint{issuer}/oidcLogoutscopes_supported/claims_supported见配置速查表默认覆盖 profile/email/phone 等常见项影响安全决策字段影响什么id_token_signing_alg_values_supported客户端据此选 ID Token 验签算法默认含none与 HS/RS/PS/ES 全家桶通常应收紧code_challenge_methods_supportedPKCE 声明默认plain,S256生产上plain没有意义token_endpoint_auth_methods_supported默认client_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt, tls_client_auth, none含匿名nonegrant_types_supported默认含password密码模式等 10 项暴露面偏大非直觉的默认值device_authorization_endpoint与token_endpoint输出同一个 URL设备码走令牌端点backchannel_logout_supported/frontchannel_logout_supported不是 discovery 子项而由cas.authn.oidc.logout.backchannel-logout-supported/frontchannel-logout-supported决定client_registration_types_supported固定为[automatic]表示支持动态客户端注册acr_values_supported默认为空列表但工厂会自动收集所有已注册 MFA Provider 的 id填充它——开了 Google Authenticator、Duo、WebAuthn 几种元数据里就自动出现几种 ACR 值无需手工维护配置了可验证凭证VC时scopes_supported还会自动追加各凭证的scope。反查入口WebFinger标准 Discovery 要求客户端先知道 issuer而 WebFinger 解决反向问题——从账号标识找 issuer。端点为{context}/oidc/.well-known/webfinger接受两个查询参数resource必填如acct:casusersso.example.orgrel可选OIDC 标准值http://openid.net/specs/connect/1.0/issuer传别的值只告警不报错。实现位于support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/discovery/webfinger/OidcDefaultWebFingerDiscoveryService.java它把resource归一化后必须为acct:形式再经OidcWebFingerUserInfoRepository默认实现之外可扩展 Groovy 脚本、RESTful 数据源用邮箱或用户名查人确认该用户确实属于本 issuer 后返回带rel链接的 JRD 文档客户端据此拼出完整 Discovery URL。查不到用户返回 404resource参数整个缺失则返回 400。配置实战按场景给配方配置模型在api/cas-server-core-api-configuration-model/src/main/java/org/apereo/cas/configuration/model/support/oidc/OidcDiscoveryProperties.java全部挂在cas.authn.oidc.discovery前缀下YAML 用 kebab-case 书写。下面四份配方覆盖最常见的诉求。配方一最小化暴露面只保留授权码 PKCE 这一条现代主路径把响应类型、grant 类型和请求对象参数一次裁齐cas: authn: oidc: discovery: response-types-supported: code grant-types-supported: authorization_code,refresh_token request-parameter-supported: false request-uri-parameter-supported: false claims-parameter-supported: false改完重新请求openid-configuration检查grant_types_supported是否只剩两项、三个布尔字段是否翻为false。配方二收紧 PKCE 与令牌端点认证默认 PKCE 含plain、令牌端点认证含none匿名生产环境都应去掉cas: authn: oidc: discovery: code-challenge-methods-supported: S256 token-endpoint-auth-methods-supported: client_secret_basic,private_key_jwt观察点code_challenge_methods_supported只剩S256token_endpoint_auth_methods_supported中不再有none与client_secret_post。配方三收敛 ID Token 签名算法默认签名算法列表横跨 HS/RS/PS/ES 且含none而对称 HS 族在 OIDC 场景基本无益可直接砍到非对称最小集cas: authn: oidc: discovery: id-token-signing-alg-values-supported: RS256,ES256 dpop-signing-alg-values-supported: RS256,ES256观察点id_token_signing_alg_values_supported字段从 13 项缩到 2 项。注意这只是声明实际验签密钥由 JWKS 端点jwks_uri指向的地址提供两者要保持一致。配方四开启 Identity Assurance 元数据verified-claims-supported默认就是true但配套的身份保证字段默认为空需要业务侧真正做证件/记录核验后才补全cas: authn: oidc: discovery: verified-claims-supported: true trust-frameworks-supported: trust_framework_example evidence-supported: id_document documents-supported: id_card claims-in-verified-claims-supported: name,email观察点响应中新增trust_frameworks_supported、evidence_supported、documents_supported等一组字段。若暂不打算对外做身份保证把开关设为false反而更干净。完整配置速查表展开查看 cas.authn.oidc.discovery.* 全部默认值布尔开关配置项默认claims-parameter-supportedtruerequest-parameter-supportedtruerequest-uri-parameter-supportedtrueauthorization-response-issuer-parameter-supportedfalsetls-client-certificate-bound-access-tokensfalserequire-pushed-authorization-requestsfalsenative-sso-supportedtrueverified-claims-supportedtruebackchannel-user-code-parameter-supportedfalse列表与算法默认值较长摘取要点配置项默认scopesopenid, profile, email, address, phone, offline_access, device_sso, client_configuration_scope, uma_authorization, uma_protection, client_registration_scopeclaimssub, acr, name, preferred_username, ... phone_number_verified, address, gender23 项标准 claimssubject-typespublic, pairwiseresponse-types-supportedcode, token, id_token, id_token token, device_coderesponse-modes-supportedquery, fragment, form_post, query.jwt, form_post.jwt, fragment.jwtprompt-values-supportednone, login, consentclaim-types-supportednormalgrant-types-supportedauthorization_code, password, client_credentials, refresh_token, ...ciba, ...pre-authorized_code, ...jwt-bearer, ...token-exchange, ...device_code, ...uma-ticket10 项introspection-supported-authentication-methodsclient_secret_basiccode-challenge-methods-supportedplain, S256token-endpoint-auth-methods-supportedclient_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt, tls_client_auth, noneid-token-signing-alg-values-supportednone, RS256/384/512, PS256/384/512, ES256/384/512, HS256/384/512id-token-encryption-alg-values-supportedRSA1_5, RSA-OAEP(-256), A*KW, A*GCMKW, ECDH-ES(A*KW)id-token-encryption-encoding-values-supportedA128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCMuser-info-signing/encryption-*与 ID Token 对应列表相同introspection-signed/encrypted-response-*同上对应列表request-object-signing/encryption-*同上对应列表dpop-signing-alg-values-supportedRS256/384/512, ES256/384/512backchannel-authentication-request-signing-alg-values-supported同 ID Token 签名列表backchannel-token-delivery-modes-supportedpoll, ping, pushacr-values-supported空自动从 MFA Provider 推导trust-frameworks-supported等 7 个身份保证集合空按需配置踩坑与边界行为现象换域名/加反代后 well-known 端点返回 404。原因issuer 校验拿请求 Host 与配置的cas.authn.oidc.issuer比对对不上直接 404 而非泄漏元数据。确认方式curl时带上-H Host: 配置的issuer域名若此时返回 200说明是代理未透传正确 Host 或 issuer 配置与对外域名不一致多域名场景可用accepted-issuers-pattern放宽匹配。现象webfinger 请求时而 400 时而 404。原因400 是resource参数整个缺失404 则是resource给了但用户查不到默认数据源查邮箱、再查用户名或resource不是acct:形式。确认方式先看响应码区分缺参与查无此人再看 CAS 日志中User/Resource not found字样。现象acr_values_supported里出现了没配置过的值。原因配置为空时工厂自动收集所有已注册MultifactorAuthenticationProvider的 id。确认方式对比已引入的 MFA 模块与响应值一一对应如需固定列表显式配置acr-values-supported即可关闭自动推导。现象声明了passwordgrant安全评审被点名。原因grant-types_supported默认含password在内的 10 项声明即我支持。确认方式用配方一收敛后复查 JSONgrant_types_supported应与实际业务允许的路径一致。现象改了 discovery 配置backchannel_logout_supported却没变。原因该字段不由discovery前缀管辖而读cas.authn.oidc.logout.backchannel-logout-supported。确认方式改对位置的开关后重启再查。现象scopes_supported多出了没配置过的 scope。原因配置了可验证凭证VC时各凭证的scope会自动并入声明。确认方式检查 VC 相关配置项的 scope 字段。验收清单部署或变更配置后按下面 6 项逐一核对把地址替换为你的实际 issuer 域名curl -s https://sso.example.org/cas/oidc/.well-known/openid-configuration返回 200且$.issuer与配置的 issuer 完全一致curl -s .../cas/oidc/.well-known与.../openid-configuration两次输出逐字段一致authorization_endpoint、token_endpoint、jwks_uri、userinfo_endpoint四个 URL 逐一可达jwks_uri返回的公钥能解开 ID Token 签名用未注册的 Host 访问curl -s -H Host: sso2.example.org https://sso.example.org/cas/oidc/.well-known/openid-configuration返回 404curl -s .../webfinger?resourceacct:casusersso.example.orgrelhttp://openid.net/specs/connect/1.0/issuer返回 200 且含 issuer 链接同一端点去掉rel参数仍 200.../webfinger不带resource参数返回 400收紧类配置算法、grant 类型在响应 JSON 中已生效且与jwks_uri实际密钥类型匹配延伸阅读与相关模块官方文档docs/cas-server-documentation/authentication/OIDC-Authentication-Discovery.md、docs/cas-server-documentation/authentication/OIDC-Authentication-WebFinger.md端点与路由support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/controllers/discovery/OidcWellKnownEndpointController.java元数据对象与工厂support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/discovery/OidcServerDiscoverySettings.java、OidcServerDiscoverySettingsFactory.javaissuer 解析与校验support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/issuer/OidcDefaultIssuerService.java下一步建议先按验收清单把端点行为确认一遍再决定要不要收紧默认值。常见后续问题有两个——Discovery 声明收紧后老客户端是否已适配以及多租户per-service issuer场景下同一台 CAS 会按请求上下文返回不同 issuer端点校验逻辑需要一并理解。【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址: https://gitcode.com/gh_mirrors/ca/cas创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考