diff --git a/README.md b/README.md index a40effc..947a593 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ CAS 5.3.16 单点登录服务(war overlay 项目,源自 CasSsoService 改版 - **构建产物是 WAR 不是 jar**:pom `packaging=war`、`finalName=cas`,CI 在 maven 构建后 `cp cas.war app.jar`(可执行 WAR,WarLauncher 直接 `java -jar`)。 - **Dockerfile 为 CAS 专用**:镜像内生成自签名 keystore(8443 HTTPS),内置 `docker/cas.properties`(仅 TLS/端口/日志)与 `etc/cas/config/log4j2.xml`;业务配置由 projman 配置管理挂载 `/app/config/application.yml`。 -- **健康检查**:`/cas/status`(HTTPS 自签名),projman 应用需配置 healthPath=`/cas/status` + HTTPS 开。 +- **健康检查**:`/status`(HTTPS 自签名),projman 应用需配置 healthPath=`/status` + HTTPS 开。(context-path 已改为根 `/`,登录地址为 `https://sso.yunhaixingtong.com/login`,不再有 `/cas` 前缀;健康检查从 `/cas/status` 变为 `/status`。) - **pom 不声明外网仓库**:依赖全部经 nexus maven-public 代理解析(内网 CI 无外网)。 -- **登录页静态文件随 WAR 打包**:`src/main/webapp/front/`(logo、native-login.js 等)入库并打进 cas.war,由 CAS 同源托管在 `/cas/front/*`。原独立的 CasSsoFront 静态仓**已废弃不用**——其中没有 `native-login.js`(登录逻辑只在本仓),Caddy 磁盘托管仅为灰度兜底。 +- **登录页静态文件随 WAR 打包**:`src/main/webapp/front/`(logo、native-login.js 等)入库并打进 cas.war,由 CAS 同源托管在 `/front/*`。原独立的 CasSsoFront 静态仓**已废弃不用**——其中没有 `native-login.js`(登录逻辑只在本仓)。 ## 推送后验证 diff --git a/build.cmd b/build.cmd index 7ad4aba..d6dd8ca 100644 --- a/build.cmd +++ b/build.cmd @@ -2,8 +2,9 @@ @set JAVA_ARGS=-Xms500m -Xmx1g @if "%CAS_SERVER_NAME%" == "" set CAS_SERVER_NAME=http://localhost:8443 -@if "%CAS_SERVER_PREFIX%" == "" set CAS_SERVER_PREFIX=http://localhost:8443/cas -@set CAS_JAVA_OVERRIDES=-Dserver.use-forward-headers=false -Dcas.server.name=%CAS_SERVER_NAME% -Dcas.server.prefix=%CAS_SERVER_PREFIX% +@if "%CAS_SERVER_PREFIX%" == "" set CAS_SERVER_PREFIX=http://localhost:8443 +@rem 根 context-path 必须用空字符串(Boot 1.5 显式拒绝 "/":Root ContextPath must be specified using an empty string) +@set CAS_JAVA_OVERRIDES=-Dserver.use-forward-headers=false -Dserver.context-path= -Dcas.server.name=%CAS_SERVER_NAME% -Dcas.server.prefix=%CAS_SERVER_PREFIX% @set CAS_DIR=\etc\cas @set CONFIG_DIR=\etc\cas\config diff --git a/docker/Dockerfile b/docker/Dockerfile index 06c276e..db292c6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,7 +1,7 @@ # CAS 5.3.16 运行镜像(单阶段,war 预构建) # CI 已先 mvn package 并在容器内把产物 cp 成固定名 target/app.jar(= cas.war,可执行 WAR) # 构建上下文 = 仓库根:docker build -f docker/Dockerfile . -# 健康检查(projman 应用配置 healthPath=/cas/status + HTTPS 自签名开):curl -fk https://localhost:8443/cas/status +# 健康检查(projman 应用配置 healthPath=/status + HTTPS 自签名开):curl -fk https://localhost:8443/status # 时区 Asia/Shanghai;JAVA_OPTS 由 projman 部署 env 注入(默认 -Xms512m -Xmx1024m) FROM eclipse-temurin:8-jre diff --git a/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationConfiguration.java b/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationConfiguration.java index 8687521..2e72002 100644 --- a/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationConfiguration.java +++ b/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationConfiguration.java @@ -10,7 +10,7 @@ import org.springframework.context.annotation.Configuration; /** * 将自定义数据库认证处理器注册进 CAS 认证执行计划, - * 使标准登录表单(/cas/login)的认证链包含数据库校验。 + * 使标准登录表单(/login)的认证链包含数据库校验。 */ @Configuration("DbAuthenticationConfiguration") public class DbAuthenticationConfiguration implements AuthenticationEventExecutionPlanConfigurer { diff --git a/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationHandler.java b/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationHandler.java index 5cd2613..823ef0b 100644 --- a/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationHandler.java +++ b/src/main/java/org/apereo/cas/web/custom/auth/DbAuthenticationHandler.java @@ -20,7 +20,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; /** - * 自定义数据库认证处理器:让 CAS 标准登录表单(/cas/login)也走数据库校验。 + * 自定义数据库认证处理器:让 CAS 标准登录表单(/login)也走数据库校验。 * 校验逻辑与 /api/login 完全一致(BCrypt + sys_user 表),保证两套登录行为统一。 * 用原生 DriverManager 直连,不依赖 CAS 内置 JdbcAuthenticationHandler 的连接池/模板, * 因此不受 WAR 中 spring-jdbc 双版本等潜在初始化问题影响。 diff --git a/src/main/java/org/apereo/cas/web/custom/controller/LoginController.java b/src/main/java/org/apereo/cas/web/custom/controller/LoginController.java index 756ce91..60cde2a 100644 --- a/src/main/java/org/apereo/cas/web/custom/controller/LoginController.java +++ b/src/main/java/org/apereo/cas/web/custom/controller/LoginController.java @@ -386,7 +386,7 @@ public class LoginController { writeJson(response, buildResponse(1, data, msg)); } else { // 原生表单提交:302 回登录页并带错误提示;同时让浏览器在成功时记住密码。 - String target = "/cas/login?error=" + URLEncoder.encode(msg, "UTF-8"); + String target = "/login?error=" + URLEncoder.encode(msg, "UTF-8"); response.sendRedirect(target); } } @@ -504,7 +504,7 @@ public class LoginController { return svcUrl + (svcUrl.contains("?") ? "&" : "?") + "ticket=" + st.getId(); } // 返回绝对 URL,确保前端无论从哪个 origin 打开都能正确跳回 CAS 同源, - // 从而把 TGC Cookie 一起带过去(相对路径 /cas/login 在非同源前端下会跳错 origin)。 + // 从而把 TGC Cookie 一起带过去(相对路径 /login 在非同源前端下会跳错 origin)。 return buildDefaultFallbackUrl(request); } catch (AuthenticationException | AbstractTicketException e) { logger.error("用户 {} 建立 SSO 会话失败", username, e); @@ -518,16 +518,29 @@ public class LoginController { /** * 构造默认落点(无 service / service 未注册 / 未配置时的回退地址)。 * 默认落点若未配置、或误配成 CAS 原生登录页路径,则强制回退到业务系统首页, - * 避免出现“登录成功却被甩回 /cas/login”的死循环(曾因 application.yml 误配踩过)。 + * 避免出现“登录成功却被甩回登录页”的死循环(曾因 application.yml 误配踩过)。 */ private String buildDefaultFallbackUrl(HttpServletRequest request) { String target = defaultRedirectUrl; - if (target == null || target.trim().isEmpty() || target.contains("/cas/login")) { + if (target == null || target.trim().isEmpty() || isCasLoginPath(target)) { target = "https://base.yunhaixingtong.com"; } return buildCasAbsoluteUrl(request, target); } + /** + * 判断地址是否指向 CAS 自身登录页(剥掉查询串后以 /login 或 /cas/login 结尾,后者兼容历史配置), + * 用于拦截误把登录页配成默认落点导致的“登录成功却被甩回登录页”死循环。 + */ + private boolean isCasLoginPath(String url) { + String path = url; + int q = path.indexOf('?'); + if (q >= 0) { + path = path.substring(0, q); + } + return path.endsWith("/login") || path.endsWith("/cas/login"); + } + /** * 基于当前请求推断 CAS 自身的访问基地址(scheme://host:port),用于构造绝对跳转 URL, * 避免前端页面不在 CAS 同源时相对路径跳转错 origin,导致 TGC Cookie 无法随跳转携带。 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d814fbb..4a7ff3c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,21 +3,27 @@ server: enabled: false port: 8443 use-forward-headers: false + # context-path 必须为根(登录地址 https://sso.yunhaixingtong.com/login,去掉 /cas 前缀)。 + # 注意:不能在这里写 server.context-path —— overlay WAR 自带的 classpath application.properties + # 显式设了 server.context-path=/cas,同在 WAR 内时 properties 优先级高于 yml,写了会被覆盖。 + # 且 Boot 1.5 规定根 context 必须用空字符串("/" 会抛 Root ContextPath must be specified + # using an empty string)。因此该键只能由外部提供:本地 build.cmd 以 -Dserver.context-path= + # 注入(系统属性优先级最高),生产由 projman 挂载的外部配置(优先于 WAR 内 classpath)设空值。 cas: # 显式声明 CAS 自身访问地址,避免根路径 / 或 /index.html 被重定向到错误端口(曾出现跳到 8080 的问题)。 # CAS 的默认值是 https://cas.example.org:8443,若运行时被外部配置覆盖成 8080,根页面重定向就会错位。 + # prefix 不带 /cas(与根 context-path 一致),CAS 内部生成的登录/注销等 URL 均由它派生。 server: name: http://localhost:8443 - prefix: http://localhost:8443/cas + prefix: http://localhost:8443 # CAS 核心配置 tgc: secure: false - # 显式指定 TGC Cookie 的 Path,必须覆盖 /cas 下所有路径(含自定义 /cas/api/login)。 - # 若不配置,CAS 默认会把 Path 留空,浏览器按“请求目录”取值: - # - 标准登录在 /cas/login 种 Cookie -> Path=/cas/ -> 正常 - # - 自定义登录在 /cas/api/login 种 Cookie -> Path=/cas/api/ -> 跳到 /cas/login 时浏览器不带此 Cookie,导致还要再登录 - path: /cas + # 显式指定 TGC Cookie 的 Path。context-path 为根后,登录页在 /login、接口在 /api/*, + # TGC 必须对全站可见,故固定 Path=/。若留空,浏览器按“请求目录”取值,行为依赖隐式推导,不可靠。 + # (历史版本曾配 /cas 以兼容 /cas/api/login 种 Cookie,context-path 改根后同步改为 /。) + path: / # 固定 TGC 加密/签名密钥。不配置的话每次重启都会自动生成新密钥, # 导致浏览器里旧 TGC Cookie 解密失败(表现为启动后首次访问的 NPE DEBUG 噪声),且启动日志反复 WARN。 crypto: diff --git a/src/main/resources/templates/casGenericSuccessView.html b/src/main/resources/templates/casGenericSuccessView.html index 2b2ad84..170efcb 100644 --- a/src/main/resources/templates/casGenericSuccessView.html +++ b/src/main/resources/templates/casGenericSuccessView.html @@ -4,7 +4,7 @@ 请稍候 - + @@ -12,17 +12,17 @@ - - - - + + + + + + + @@ -22,7 +22,7 @@