This repository has been archived on 2026-09-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
UserBaseFront/service/src/main/java/com/yunhai/userbase/config/CasSsoConfiguration.java
T

90 lines
4.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.yunhai.userbase.config;
import com.yunhai.platform.auth.spring.YhSsoProperties;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 浏览器端 CAS 单点登录过滤器(仅作用于 {@code /api/*})。<br><br>
* 基础平台 yh-auth 只负责「读 CAS 登录态 + 补全用户明细」,并不提供浏览器重定向;
* 本配置补齐标准 CAS 客户端三件套:<br>
* 1) {@link SingleSignOutFilter} 单点登出;<br>
* 2) {@link AuthenticationFilter} 未登录时重定向到 CAS 登录页;<br>
* 3) {@link Cas20ProxyReceivingTicketValidationFilter} 校验 service ticket 并建立会话;<br>
* 4) {@link HttpServletRequestWrapperFilter} 让 {@code request.getRemoteUser()} 可用(yh-auth 的
* {@code CasSessionAuthStrategy} 依赖它)。<br><br>
* 顺序须早于 yh-app-auth 的 {@code AppAuthFilter}(HIGHEST_PRECEDENCE+10),
* 且只对 {@code /api/*} 生效;{@code /oapi}、{@code /open/api} 走签名验签,不在此列。
*/
@Configuration
@ConditionalOnProperty(prefix = "yh.sso", name = "server-url-prefix")
public class CasSsoConfiguration {
@Autowired
private YhSsoProperties ssoProperties;
/** 从 client-host-url 抽取 scheme://host[:port](去掉上下文路径),供给 CAS 构造 service 参数。 */
private String serverName() {
String client = ssoProperties.getClientHostUrl();
if (client == null || client.trim().isEmpty()) {
return null;
}
Matcher m = Pattern.compile("^(https?://[^/]+)").matcher(client.trim());
return m.find() ? m.group(1) : client.trim();
}
@Bean
public FilterRegistrationBean<SingleSignOutFilter> casSingleSignOutFilter() {
FilterRegistrationBean<SingleSignOutFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new SingleSignOutFilter());
bean.addUrlPatterns("/api/*");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 5);
return bean;
}
@Bean
public FilterRegistrationBean<AuthenticationFilter> casAuthenticationFilter() {
FilterRegistrationBean<AuthenticationFilter> bean = new FilterRegistrationBean<>();
AuthenticationFilter filter = new AuthenticationFilter();
filter.setCasServerLoginUrl(ssoProperties.getServerUrlPrefix() + "/login");
filter.setServerName(serverName());
bean.setFilter(filter);
bean.addUrlPatterns("/api/*");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 6);
return bean;
}
@Bean
public FilterRegistrationBean<Cas20ProxyReceivingTicketValidationFilter> casValidationFilter() {
FilterRegistrationBean<Cas20ProxyReceivingTicketValidationFilter> bean = new FilterRegistrationBean<>();
Cas20ProxyReceivingTicketValidationFilter filter = new Cas20ProxyReceivingTicketValidationFilter();
filter.setServerName(serverName());
bean.setFilter(filter);
// cas-client 3.5.1 的校验过滤器无 setCasServerUrlPrefix 设值器,需经 init-parameter 注入
bean.addInitParameter("casServerUrlPrefix", ssoProperties.getServerUrlPrefix());
bean.addUrlPatterns("/api/*");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 7);
return bean;
}
@Bean
public FilterRegistrationBean<HttpServletRequestWrapperFilter> casHttpServletRequestWrapperFilter() {
FilterRegistrationBean<HttpServletRequestWrapperFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new HttpServletRequestWrapperFilter());
bean.addUrlPatterns("/api/*");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 8);
return bean;
}
}