主题
CAS集成示例
环境信息
后续章节配置信息参考如下环境信息,实际集成需要将其替换为正式地址
- 认证服务地址:
https://authserver.xxx.edu.cn/authserver - 应用地址:
https://xxx.xxx.edu.cn
提示
如果应用端口号使用非标准端口号(HTTP: 80、HTTPS: 443),则需要添加实际的端口信息,比如:https://xxx.xxx.edu.cn:8005。
Java
提示
CIAP提供的CAS认证方式为标准的CAS协议,本文提供的示例是基于CIAP提供的SDK客户端实现,若您使用CAS官方提供的客户端,会存在差异,可直接参考Client官方网站部分集成。
使用web.xml配置
添加依赖
将web.xml方式集成下的cas-client-core-3.2.1.jar文件拷贝到客户端应用所在服务器中,并将存放这些jar包的路径设置到应用的classpath中。比如WebContent\WEB-INF\lib中。
修改web.xml文件
红色部分需要修改为实际参数。
xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- ==================== 单点登录开始 ================ -->
<!-- 用于单点退出,该监听器和过滤器用于实现单点登出功能,可选配置 -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<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>
<filter-name>CASFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<!--这里的server是CAS服务端的登录地址,login为固定值-->
<param-value>https://authserver.xxx.edu.cn/authserver/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<!--这里是应用地址,注意是域名:端口或者ip:端口-->
<param-value>https://xxx.xxx.edu.cn</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
<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>
<!--这里的server是CAS服务端的地址,这里不要加login-->
<param-value>https://authserver.xxx.edu.cn/authserver</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<!--这里是应用地址,注意是域名:端口或者ip:端口-->
<param-value>https://xxx.xxx.edu.cn</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>
<!-- 该过滤器负责实现HttpServletRequest请求的包裹,比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名。 -->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- =============== 单点登录结束 ================= -->
</web-app>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
获取用户信息
第三方应用在配置好web.xml之后,需要调整代码用集成之后的方式获取当前登录用户。获取用户信息的示例代码如下:
java
// cas-client-3.2.1版本集成
String uid = request.getRemoteUser();
String cn = "";
Principal principal = request.getUserPrincipal();
if(principal != null && principal instanceof AttributePrincipal){
AttributePrincipal aPrincipal = (AttributePrincipal)principal;
// 获取用户信息中公开的Attributes部分
Map<String, Object> map = aPrincipal.getAttributes();
// 获取姓名,可以根据属性名称获取其他属性
cn = (String)map.get("cn");
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
集成应用退出
第三方应用在退出的时候需要重定向跳转到CIAP的退出地址,具体示例代码如下(红色部分需要根据实际情况调整),被集成业务系统退出,必须用调用身份认证的退出地址,并且要清除业务系统自身的cookie。
java
session.invalidate();
// CIAP的退出地址
String casLogoutURL = "https://authserver.xxx.edu.cn/authserver/logout";
// service后面带的参数为应用的访问地址,需要使用URLEncoder进行编码
String redirectURL = casLogoutURL + "?service="
+ URLEncoder.encode("https://xxx.xxx.edu.cn/caslogin.jsp");
response.sendRedirect(redirectURL);1
2
3
4
5
6
7
2
3
4
5
6
7
白名单(认证不拦截)
在第三方应用的web.xml中添加以下内容:(加色部分需要修改为实际参数),符合白名单规则的地址,不被身份认证拦截。白名单的配置仅支持正则表达式匹配。
xml
<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://authserver.xxx.edu.cn/authserver/login</param-value>
</init-param>
<!---仅支持正则表达式匹配,支持英文逗号分隔,可以配置多个-->
<init-param>
<param-name>casWhiteUrl</param-name>
<param-value>/demo.*/index.jsp</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://xxx.xxx.edu.cn</param-value>
</init-param>
</filter>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
使用Spring Boot配置
添加依赖
xml
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.5.0</version>
</dependency>1
2
3
4
5
2
3
4
5
编写配置类
java
package com.example.demo.config;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class CasAutoConfig {
private final static String URL_PATTERN = "/*";
@Value("${cas.server-url-prefix}")
private String serverUrlPrefix;
@Value("${cas.server-login-url}")
private String serverLoginUrl;
@Value("${cas.client-host-url}")
private String clientHostUrl;
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
ServletListenerRegistrationBean listenerRegistrationBean = new ServletListenerRegistrationBean();
listenerRegistrationBean.setListener(new SingleSignOutHttpSessionListener());
listenerRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return listenerRegistrationBean;
}
/**
* 单点登录退出
*/
@Bean
public FilterRegistrationBean singleSignOutFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new SingleSignOutFilter());
registrationBean.addUrlPatterns(URL_PATTERN);
registrationBean.addInitParameter("casServerUrlPrefix", serverUrlPrefix);
registrationBean.setName("CAS Single Sign Out Filter");
registrationBean.setOrder(2);
return registrationBean;
}
/**
* 单点登录认证
*/
@Bean
public FilterRegistrationBean AuthenticationFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new AuthenticationFilter());
registrationBean.addUrlPatterns(URL_PATTERN);
registrationBean.setName("CAS Filter");
Map<String, String> initParameters = new HashMap<>();
initParameters.put("casServerLoginUrl", serverLoginUrl);
initParameters.put("serverName", clientHostUrl);
// 可以配置不需要单点登录拦截url(例子是如果url中包含/logout或者/index,则不需要经过单点登录验证)
// 没有可以注释
initParameters.put("ignorePattern", "/logout|/index");
// 配置不需要单点登录拦截url结束
registrationBean.setInitParameters(initParameters);
registrationBean.setOrder(3);
return registrationBean;
}
/**
* 单点登录校验
*/
@Bean
public FilterRegistrationBean Cas30ProxyReceivingTicketValidationFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
registrationBean.addUrlPatterns(URL_PATTERN);
registrationBean.setName("CAS Validation Filter");
registrationBean.addInitParameter("casServerUrlPrefix", serverUrlPrefix);
registrationBean.addInitParameter("serverName", clientHostUrl);
registrationBean.setOrder(4);
return registrationBean;
}
/**
* 单点登录请求包装
*/
@Bean
public FilterRegistrationBean httpServletRequestWrapperFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new HttpServletRequestWrapperFilter());
registrationBean.addUrlPatterns(URL_PATTERN);
registrationBean.setName("CAS HttpServletRequest Wrapper Filter");
registrationBean.setOrder(5);
return registrationBean;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
添加配置
properties
# 认证地址,到上下文,必须配置
cas.server-url-prefix=https://authserver.xxx.edu.cn/authserver
# 认证登录地址,必须配置
cas.server-login-url=https://authserver.xxx.edu.cn/authserver/login
# 客户端地址,必须配置,配置自己系统访问地址即可,域名地址也可以
cas.client-host-url=https://xxx.xxx.edu.cn
# 以下两个配置本身应用就有的
server.port=80
server.servlet.context-path=/demo1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Client官方网站
https://github.com/apereo/java-cas-client是Java Apereo CAS客户端的官方网站。该客户端由一组适用于大多数基于Java的Web应用程序的Servlet过滤器组成。它还作为一个API平台,用于通过编程方式与CAS服务器交互,发起身份验证请求、验证票据并获取主体属性。

