Appearance
CAS Overlay Template 4.x 版本指南
官方介绍
CAS Overlay Template 4.x 是 Apereo CAS 项目的官方推荐部署方式,它基于 Apache Maven 的 overlay 机制,允许开发者在不修改 CAS 源代码的情况下进行定制化开发。Overlay 模板提供了一种干净、可维护的方式来集成 CAS 并添加自定义功能。
CAS (Central Authentication Service) 4.x 是一个企业级的单点登录系统,支持多种认证协议,包括 SAML1.1、SAML2、CAS 协议等。
版本特性
核心特性
- 轻量级部署: 基于 Spring Framework,简化了部署过程
- 模块化架构: 支持插件化扩展
- 协议支持: 支持 CAS、SAML1.1、SAML2
- 多认证源: 支持 LDAP、数据库、JAAS、RDBMS 等多种认证方式
- 安全性: 内置安全机制,支持 MFA(多因素认证)
4.x 版本演进
- 4.0.x: 初始版本,奠定了基础架构
- 4.1.x: 增强了配置管理,改进了安全性
- 4.2.x: 改进了对 Spring Webflow 的集成,支持更多认证协议,改进了性能
- 4.3.x: 增强了对 REST 接口的支持,增强了监控和日志功能
- 4.4.x: 最终长期支持版本,提供了更好的稳定性,增加了对 JWT、OAuth2 的更好支持
官方获取地址
bash
# 通过 Git Clone 获取 CAS Overlay Template 4.x
git clone -b 4.2.x https://github.com/apereo/cas-overlay-template.git cas-overlay-4.x1
2
2
或者指定特定版本:
bash
git clone -b 4.2.7 https://github.com/apereo/cas-overlay-template.git cas-overlay-4.2.71
环境要求
- Java: JDK 8 或更高版本
- Maven: 3.2.1 或更高版本
- Git: 用于版本控制
- 操作系统: 跨平台支持(Linux、Windows、macOS)
部署方法
1. 克隆项目
bash
git clone -b 4.2.x https://github.com/apereo/cas-overlay-template.git cas-overlay-4.x
cd cas-overlay-4.x1
2
2
2. 构建项目
bash
# 清理并构建项目
mvn clean compile
# 构建 WAR 包
mvn clean package
# 直接运行(开发模式)
mvn clean spring-boot:run1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
3. 配置文件说明
CAS 4.x 使用以下配置文件:
application.properties
properties
# 服务器配置
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=file:/etc/cas/thekeystore
server.ssl.key-store-password=changeit
server.ssl.key-password=changeit
# CAS 服务器名称
cas.server.name=https://cas.example.org:8443
cas.server.prefix=https://cas.example.org:8443/cas
# 认证配置
cas.authn.accept.users=casuser::Mellon
# 日志配置
logging.config=file:/etc/cas/log4j2.xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
4. 部署到应用服务器
bash
# 构建 WAR 文件
mvn clean package
# 将生成的 WAR 文件部署到 Tomcat
cp target/cas.war /path/to/tomcat/webapps/1
2
3
4
5
2
3
4
5
二次开发
自定义认证处理器
创建自定义认证处理器示例:
src/main/java/com/example/CustomAuthenticationHandler.java
java
package com.example;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.jasig.cas.authentication.principal.PrincipalFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
@Component("customAuthenticationHandler")
public class CustomAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
public CustomAuthenticationHandler() {
super();
}
@Autowired
public CustomAuthenticationHandler(PrincipalFactory principalFactory) {
super(principalFactory);
}
@Override
protected HandlerResult doAuthentication(UsernamePasswordCredential credential) throws GeneralSecurityException, PreventedException {
String username = credential.getUsername();
String password = credential.getPassword();
// 自定义认证逻辑
if (authenticateUser(username, password)) {
return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
} else {
throw new FailedLoginException("Authentication failed");
}
}
private boolean authenticateUser(String username, String password) {
// 实现您的认证逻辑
return "admin".equals(username) && "password".equals(password);
}
}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
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
自定义属性解析器
src/main/java/com/example/CustomPersonAttributeDao.java
java
package com.example;
import org.jasig.services.persondir.IPersonAttributes;
import org.jasig.services.persondir.support.NamedStubPersonAttributeDao;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component("customPersonAttributeDao")
public class CustomPersonAttributeDao extends NamedStubPersonAttributeDao {
@Override
public IPersonAttributes getPerson(String uid) {
Map<String, List<Object>> attributes = new HashMap<>();
// 添加自定义属性
attributes.put("mail", List.of(uid + "@example.org"));
attributes.put("displayName", List.of("User " + uid));
attributes.put("memberOf", List.of("GROUP1", "GROUP2"));
return new org.jasig.services.persondir.support.StubPersonAttributeTO(uid, attributes);
}
}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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
自定义视图
在 src/main/resources/templates 目录下可以自定义 CAS 的视图模板。例如,创建自定义登录页面:
src/main/resources/templates/casLoginView.html
html
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout}">
<head>
<meta charset="UTF-8"/>
<title>CAS Login</title>
</head>
<body>
<div layout:fragment="content">
<div class="box fl-panel">
<h2>Custom Login Form</h2>
<form method="post" th:object="${credential}" id="fm1" class="fm-v clearfix">
<div class="row fl-controls-left">
<label for="username" class="fl-label">Username:</label>
<input class="required" id="username" size="25" tabindex="1"
type="text" th:field="*{username}"
autocomplete="off" />
</div>
<div class="row fl-controls-left">
<label for="password" class="fl-label">Password:</label>
<input class="required" id="password" size="25" tabindex="2"
type="password" th:field="*{password}"
autocomplete="off" />
</div>
<div class="row btn-row">
<input type="hidden" name="execution" th:value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input type="hidden" name="geolocation" />
<input class="btn-submit" name="submit" accesskey="l"
th:value="#{screen.welcome.button.login}"
tabindex="6" type="submit" />
</div>
</form>
</div>
</div>
</body>
</html>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
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
配置示例
LDAP 认证配置
application.properties
properties
# LDAP 配置
cas.authn.ldap[0].type=AUTHENTICATED
cas.authn.ldap[0].ldapUrl=ldaps://ldap.example.org:636
cas.authn.ldap[0].baseDn=ou=people,dc=example,dc=org
cas.authn.ldap[0].userFilter=uid={user}
cas.authn.ldap[0].bindDn=cn=admin,dc=example,dc=org
cas.authn.ldap[0].bindCredential=password
cas.authn.ldap[0].principalAttributeList=uid,sn,givenName,mail
cas.authn.ldap[0].principalIdAttribute=uid1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
数据库认证配置
application.properties
properties
# 数据库认证配置
cas.authn.jdbc.query[0].sql=SELECT password FROM users WHERE username=?
cas.authn.jdbc.query[0].healthQuery=SELECT 1
cas.authn.jdbc.query[0].isolateInternalQueries=false
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/cas
cas.authn.jdbc.query[0].failFast=true
cas.authn.jdbc.query[0].isolationLevelName=ISOLATION_READ_COMMITTED
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQL5Dialect
cas.authn.jdbc.query[0].leakThreshold=10
cas.authn.jdbc.query[0].propagationBehaviorName=PROPAGATION_REQUIRED
cas.authn.jdbc.query[0].batchSize=1
cas.authn.jdbc.query[0].user=database_user
cas.authn.jdbc.query[0].password=database_password
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.query[0].name=QUERY1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Demo 示例
简单的 Hello World 示例
创建一个简单的 CAS 客户端应用来演示集成:
pom.xml
xml
<dependencies>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>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://cas.example.org:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://client.example.org:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>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
常见问题和解决方案
1. SSL 证书问题
如果遇到 SSL 证书问题,可以临时禁用 SSL 验证(仅用于开发环境):
properties
cas.server.ssl.validation=false1
2. 认证失败问题
检查日志文件以确定认证失败的原因:
bash
tail -f /path/to/catalina.out1
3. 内存溢出问题
增加 JVM 内存设置:
bash
export JAVA_OPTS="-Xms512m -Xmx2048m -XX:MaxPermSize=512m"1
性能优化
连接池配置
properties
# 数据库连接池
cas.jdbc.pool.minSize=2
cas.jdbc.pool.maxSize=10
cas.jdbc.pool.maxWait=2000
# LDAP 连接池
cas.authn.ldap[0].minPoolSize=3
cas.authn.ldap[0].maxPoolSize=10
cas.authn.ldap[0].validateOnCheckout=true1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
缓存配置
properties
# EhCache 配置
cas.ticket.registry.ehcache.maxElementsInMemory=1000
cas.ticket.registry.ehcache.eternal=false
cas.ticket.registry.ehcache.timeToLive=28800
cas.ticket.registry.ehcache.timeToIdle=288001
2
3
4
5
2
3
4
5
升级指南
从 4.1.x 升级到 4.2.x:
- 备份现有配置
- 更新 pom.xml 中的 CAS 版本
- 检查废弃的配置属性
- 测试认证流程
- 部署到生产环境
总结
CAS Overlay Template 4.x 提供了一种简单而强大的方式来部署和自定义 CAS 服务。通过 overlay 机制,开发者可以轻松地添加自定义功能,同时保持与上游版本的兼容性。虽然 4.x 系列已经不再积极维护,但对于仍在使用该版本的组织来说,这个模板仍然是一个很好的起点。