CAS (Central Authentication Service) 是企業級單點登入標準協議。Spring Boot 整合 Spring Security CAS 模組,可快速實現應用接入 CAS Server 的認證、登出、代理票據驗證。本文提供基於 Spring Boot 2.x/3.x 的完整配置類、屬性綁定、自定義 UserDetailsService、權限映射全流程。
/login?service=...。/login?ticket=ST-xxx。CasAuthenticationFilter 攔截 Ticket → CasAuthenticationProvider 驗證 Ticket (調用 CAS /p3/serviceValidate) → 獲取用戶屬性 → 載入本地權限 → 建立 Authentication。/logout → CAS /logout → 通知所有應用銷毀 Session (SingleSignOutFilter)。
cas:
server:
url: https://sso.example.com:8443/cas
login-url: ${cas.server.url}/login
logout-url: ${cas.server.url}/logout?service=${app.url}
client:
service-url: https://app.example.com:8080
login-url: /login/cas
logout-url: /logout/cas
app:
url: https://app.example.com:8080
4. 核心 Security 配置類
5. 自定義 UserDetailsService:Ticket 驗證後載入權限
roles = (List) attrs.get("roles"); // 如 ["USER","ADMIN"] // 實際應查詢本地 DB 同步/補全用戶信息 UserDetails user = User.builder() .username(username) .password("") // CAS 免密,密碼無意義 .authorities(roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList())) .build(); return user; } } 6. Spring Boot 3.x / Spring Security 6 寫法差異
logout.permitAll()) .exceptionHandling(ex -> ex.authenticationEntryPoint(casAuthenticationEntryPoint())) .addFilter(casAuthenticationFilter()) .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class) .addFilterBefore(casLogoutFilter(), LogoutFilter.class) .csrf(csrf -> csrf.disable()) .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)); return http.build(); }7. CAS Server 端配置要點 (應用註冊)
serviceId = https://app.example.com:8080/**。principal (用戶名)、email、roles 等屬性。/samlLogout),應用端 SingleSignOutFilter 處理。| 現象 | 原因/解決 |
|---|---|
| Ticket 驗證失敗: "Ticket not recognized" | Service URL 不匹配 (含/不含尾斜線、HTTP/HTTPS、端口)。確保 serviceProperties.setService 與 CAS 註冊的 serviceId 完全一致。 |
| 無限重定向登入頁 | Ticket 驗證成功但 AuthenticationUserDetailsService 拋異常/返回 null,導致 Security 認為未認證。檢查日誌、斷點調試。 |
| 單點登出不生效 | 1) CAS Server 未配置該應用的登出回調 URL。2) 應用缺少 SingleSignOutFilter 或順序錯誤。3) 會話追蹤依賴 sessionMappingStorage (預設內存),集群需共享存儲 (Redis/JDBC)。 |
| HTTPS 憑證信任 | 應用調用 CAS /p3/serviceValidate 需信任 CAS 憑證。將 CA 導入 JDK cacerts 或配置 Cas20ServiceTicketValidator.setTrustStore。 |