feat(auth): support standard CAS 2.0/3.0 SSO protocol#464
Open
dongmucat wants to merge 3 commits into
Open
Conversation
Implement native CAS protocol ticket validation for enterprise SSO integration, supporting both CAS 2.0 (XML) and CAS 3.0 (JSON) modes. Backend: - Introduce IdentityClaims interface to abstract identity providers; OAuthClaims now implements it, enabling CAS reuse of IdentityBindingService - CasProperties with @PostConstruct HTTPS validation and feature flag - CasTicketValidator: validates tickets via /serviceValidate (2.0) or /p3/serviceValidate (3.0), parses XML/JSON responses - CasLoginController: /api/v1/auth/cas/login (redirect) and /callback (ticket validation + session establishment) - RouteSecurityPolicyRegistry: permit /api/v1/auth/cas/** - AuthMethodCatalog: expose CAS as CAS_REDIRECT method type Frontend: - LoginButton renders CAS_REDIRECT methods alongside OAuth providers - Runtime config adds authCasEnabled flag - CAS logo SVG added Closes #456
…ase wiring
Blockers:
- Harden XML parsing against XXE (disallow DOCTYPE, external entities/DTDs,
enable FEATURE_SECURE_PROCESSING) and switch to UTF-8 byte decoding.
- Generalize AccessPolicy.evaluate from OAuthClaims to IdentityClaims; extract
IdentityAuthenticator so OAuth and CAS share allow/deny/pending evaluation.
CAS callback now goes through the policy instead of bypassing it with a
direct bindOrCreate call.
- Configure JDK HttpClient with connect/read timeouts (5s/10s) and disable
HTTP redirects to prevent ticket exfiltration via a malicious CAS server.
Major:
- Require HTTPS for skillhub.auth.cas.service-url in addition to server-url.
- Stop logging raw service tickets; log claims.subject() instead.
- Remove the dead authCasEnabled web flag — the backend AuthMethodCatalog is
the single source of truth for CAS visibility, matching how OAuth works.
- Wire SKILLHUB_AUTH_CAS_* env vars into compose.release.yml and add a fully
documented section in .env.release.example.
Minor:
- CasProtocolVersion enum replaces string comparisons in the validator.
- JSON multi-value array attributes are preserved as List<String> instead of
silently dropping all but the first element.
- AuthMethod.methodType union adds 'CAS_REDIRECT'.
- application.yml notes that service-url must equal
${SKILLHUB_PUBLIC_BASE_URL}/api/v1/auth/cas/callback.
Tests:
- CasTicketValidatorTest tightens URL matching to assert ticket/service/format
parameters and adds XXE + billion-laughs regression cases.
- IdentityAuthenticatorTest covers ALLOW / PENDING / DENY paths.
- AuthMethodCatalogTest exercises both cas.enabled=true and =false.
- isExternalRedirectMethod predicate extracted and unit-tested.
Collaborator
Author
|
Pushed Blockers
Major
Minor
Quality gates
Open follow-ups not in scope here:
|
…kage, CSRF B1 — Ticket log leak: log.debug now records only the validation path (resolvedProtocolVersion().validatePath()); the catch block surfaces only e.getClass().getSimpleName() instead of e.getMessage(), preventing the full validation URL (with ticket query param) from reaching log streams. B2 — emailVerified semantics: CasIdentityClaims.emailVerified() now constantly returns false. CAS passes through email attributes from the upstream directory (LDAP/AD) without cryptographic verification, so returning true was a false signal to any AccessPolicy that gates on it. B3 — Exception package: AccountPendingException and AccountDisabledException moved from auth.oauth to auth.identity; all import sites updated. OAuth, CAS, and future SAML/OIDC flows now import from the neutral package. S6 — Login CSRF via state nonce: login() generates a cryptographically random 24-byte nonce, stores it in the session under a CAS-specific key (skillhub.cas.state), and appends state=<nonce> to the service URL that is sent to the CAS server. callback() validates the incoming state param against the session value before touching the ticket; a mismatch short- circuits to redirect:/login?error=invalid_state. The CAS-specific session key (skillhub.cas.state / skillhub.cas.returnTo) also eliminates the previous shared-key concurrency hazard with the OAuth flow.
Collaborator
Author
|
Pushed B1 — Ticket log leak
B2 —
B3 — Exception package
S6 — Login CSRF via state nonce
Quality gates
Remaining |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
实现标准 CAS 2.0/3.0 协议的 SSO 登录集成,复用现有 IdentityBindingService 身份映射抽象,使 OSS 用户可以对接 Apereo CAS Server、Keycloak CAS adapter 等主流实现。
变更内容
后端实现
IdentityClaims接口(provider-neutral 身份声明抽象),OAuthClaims改为实现该接口IdentityBindingService.bindOrCreate入参从OAuthClaims泛化为IdentityClaimscom.iflytek.skillhub.auth.cas包:CasProperties:配置类,含@PostConstructHTTPS 强校验 + feature flagCasTicketValidator:调用 CAS server 的 serviceValidate 端点,支持 3.0 JSON 和 2.0 XML 解析CasLoginController:/api/v1/auth/cas/login(重定向到 CAS)和/callback(票据验证 + 会话建立)CasIdentityClaims:将 CAS attributes 适配为IdentityClaimsCasValidationException:票据验证失败异常RouteSecurityPolicyRegistry放行/api/v1/auth/cas/**AuthMethodCatalog在 CAS 启用时暴露CAS_REDIRECT方法类型前端实现
LoginButton组件同时渲染OAUTH_REDIRECT和CAS_REDIRECT类型的登录按钮RuntimeConfig新增authCasEnabled字段30-runtime-config.sh新增SKILLHUB_WEB_AUTH_CAS_ENABLED环境变量cas-logo.svg配置项
测试覆盖
CasTicketValidatorTest:8 个用例覆盖 JSON/XML 成功、失败、缺失字段、数组属性、禁用状态CasLoginControllerTest:12 个用例覆盖重定向、回调成功/失败、returnTo 处理、账户状态异常安全考虑
allow-insecure-server=true才能用 HTTP(仅限开发)OAuthLoginRedirectSupport.sanitizeReturnTo()防止 open redirectPlatformSessionService.establishSession内置处理相关 Issue
Closes #456
测试说明
本地验证步骤
application.yml中启用 CAS 并配置 CAS server 地址/api/v1/auth/methods确认返回 CAS 方法回归测试范围