使用 Spring(启动)配置 CAS,而不使用 web.xml

Configure a CAS with Spring (Boot) without web.xml

我正在使用 Boot 将 WebApp 从 Spring 3 移植到 Spring 4。

原文web.xml下面

<listener>
 <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

<filter>
 <filter-name>CAS Authentication Filter</filter-name>
 <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
 <init-param>
    <param-name>casServerLoginUrl</param-name>
    <param-value>https://casserver/login</param-value>
 </init-param>
 <init-param>
    <param-name>serverName</param-name>
    <param-value>http://myapp</param-value>
 </init-param>
</filter>

<filter>
 <filter-name>CAS Validation Filter</filter-name>
 <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
 <init-param>
    <param-name>casServerUrlPrefix</param-name>
    <param-value>https://casserver/login</param-value>
 </init-param>
 <init-param>
    <param-name>serverName</param-name>
    <param-value>http://myapp</param-value>
 </init-param>
 <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
 </init-param>
</filter>

<filter>
 <filter-name>CAS Single Sign Out Filter</filter-name>
 <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>

<filter-mapping>
 <filter-name>CAS Single Sign Out Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
 <filter-name>CAS Authentication Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
 <filter-name>CAS Validation Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

<session-config>
 <session-timeout>90</session-timeout>
</session-config>

<context-param>
 <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
 <param-value>messages</param-value>
</context-param>

我正在尝试在我的 AppConfic class 中注册所有过滤器、侦听器和映射(下面未完成,因为它已经无法工作...)

@Configuration
public class MyWebApplicationInitializer implements ServletContextInitializer  {

    @Override
    public void onStartup(ServletContext servletContext) {
        servletContext.addListener(new SingleSignOutHttpSessionListener());

        Cas20ProxyReceivingTicketValidationFilter cas20 = new Cas20ProxyReceivingTicketValidationFilter();
        cas20.setServerName("http://myapp");

        AuthenticationFilter authenticationFilter = new AuthenticationFilter();
        authenticationFilter.setCasServerLoginUrl("https://casserver");
        authenticationFilter.setServerName("http://myapp");

        servletContext.addFilter("CAS Authentication Filter", authenticationFilter);
        servletContext.addFilter("CAS Validation Filter", cas20);
        servletContext.addFilter("CAS Single Sign Out Filter", new SingleSignOutFilter());
    }
}

1/ CAS20实例化问题

我无法定义 cas20 casServerUrlPrefix...没有 setter ?!

2/ AuthenticationFilter问题

即使定义了 serverName,在启动过程中,也会出现以下错误:

java.lang.IllegalArgumentException: serverName or service must be set.
    at org.jasig.cas.client.util.CommonUtils.assertTrue(CommonUtils.java:116) ~[cas-client-core-3.2.1.jar:3.2.1]
    at org.jasig.cas.client.util.AbstractCasFilter.init(AbstractCasFilter.java:103) ~[cas-client-core-3.2.1.jar:3.2.1]
    at org.jasig.cas.client.authentication.AuthenticationFilter.init(AuthenticationFilter.java:96) ~[cas-client-core-3.2.1.jar:3.2.1]
    at org.jasig.cas.client.util.AbstractCasFilter.init(AbstractCasFilter.java:84) ~[cas-client-core-3.2.1.jar:3.2.1]
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109) ~[tomcat-embed-core-8.0.28.jar:8.0.28]

是否可以在 ServletContextInitializer 中定义这种过滤器?我是否必须加载一个 xml (dispatcher-servlet.xml 之类的?)

我强烈建议阅读 Servlet 3.0 spec 以及它的工作原理,如果您知道自己在做什么,那么 web.xml 可以完美移植。您只需要在注册时指定初始化参数即可。

<filter>
 <filter-name>CAS Validation Filter</filter-name>
 <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
 <init-param>
    <param-name>casServerUrlPrefix</param-name>
    <param-value>https://casserver/login</param-value>
 </init-param>
 <init-param>
    <param-name>serverName</param-name>
    <param-value>http://myapp</param-value>
 </init-param>
 <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
 </init-param>
</filter>

有了这个

<filter-mapping>
 <filter-name>CAS Validation Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

在 Java 中使用 WebApplicationInitializer.

会大致导致以下结果
@Configuration
public class MyWebApplicationInitializer implements ServletContextInitializer  {

    @Override
    public void onStartup(ServletContext sc) {
        FilterRegistration.Dynamic cas20Registration = sc.addFilter("CAS Validation Filter", Cas20ProxyReceivingTicketValidationFilter.class);
        cas20Registration.setInitParameter("casServerUrlPrefix casServerUrlPrefix", "https://casserver/login");
        cas20Registration.setInitParameter("serverName", "http://myapp");
        cas20Registration.setInitParameter("encoding", "UTF-8");
        cas20Registration.addMappingForUrlPatterns(null, false, "/*");
    }
}

以上是 xml 到 java 的一对一翻译。这应该让您了解其他过滤器。

但是您使用的是 Spring 引导,这样更容易。只需在 Spring 引导参考指南中创建一个 @Bean 方法,其中 returns 一个 FilterRegistrationBean for the desired filters. See also the appropriate section

@Bean
public FilterRegistrationBean cas20Registration() {
    FilterRegistrationBean cas20 = new FilterRegistrationBean();
    cas20.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
    cas20.addUrlPatterns("/*");
    cas20.addInitParameter("casServerUrlPrefix casServerUrlPrefix", "https://casserver/login");
    cas20.addInitParameter("serverName", "http://myapp");
    cas20.addInitParameter("encoding", "UTF-8");        
    return cas20;
}

您可以对其他过滤器、侦听器和所需组件执行相同的操作。

但是有一件事情是您不能使用基于 java 的配置来做的,那就是设置会话超时值。但是,您可以简单地将其移至 application.properties 并添加 server.session.timeout 属性。您需要将该值乘以 60,因为在 web.xml 中它以分钟为单位,而在属性文件中它预计以秒为单位。

server.session.timeout=5400 # 90 minutes