- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
Apereo CAS 将认证过程中产生的各类事件(登录成功、登录失败、票据创建等)封装为统一的事件模型,并交由事件仓库(CasEventRepository)持久化。当事件仓库后端选用 MongoDB 时,认证事件会被写入 MongoDB 的指定集合中,供审计、监控、事件报表与风险分析使用。读完本文,你将掌握如何通过cas-server-support-events-mongo模块启用该能力、完整配置 MongoDB 连接与集合参数,并理解事件从产生、落库到被events管理端点查询的底层实现链路。
一、模块概述与启用方式
MongoDb 认证事件持久化由独立模块 cas-server-support-events-mongo 提供,其核心作用正如官方文档所述:将认证事件存储到 MongoDB NoSQL 数据库中("Stores authentication events into a MongoDb NoSQL database")。
启用方式是在 CAS 构建配置(Gradle 依赖管理)中加入该模块,坐标信息如下:
依赖模块:cas-server-support-events-mongo 组织:org.apereo.cas加入依赖后,CAS 会自动装配 CasMongoDbEventsAutoConfiguration 中定义的三个核心 Bean:
| Bean 名称 | 类型 | 职责 |
|---|---|---|
persistenceExceptionTranslationPostProcessor | PersistenceExceptionTranslationPostProcessor | 将 MongoDB 数据访问异常转换为 Spring 持久化异常体系 |
mongoEventsTemplate | MongoTemplate | 面向事件集合的 MongoDB 操作模板,负责建集合与读写 |
casEventRepository | CasEventRepository | 事件仓库实现(MongoDbCasEventRepository),供 CAS 全局事件发布与消费使用 |
该自动配置类同时具备两个重要的装配前提:
- 通过
@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.Events, module = "mongo")限定:只有 CAS 的Events 功能特性与mongo 模块特性均被启用时才生效。该特性开关通常由cas.feature-flags相关配置或模块自动推导控制。 mongoEventsTemplate与mongoEventRepositoryFilter均标注@ConditionalOnMissingBean,意味着开发者可以覆盖这些 Bean,自定义连接模板或事件过滤策略。casEventRepository通过@Qualifier("mongoEventsTemplate")注入 MongoDB 模板,通过@Qualifier("mongoEventRepositoryFilter")注入事件过滤器。
1.1 从源码看事件入库链路
在 MongoDbCasEventRepository 中,事件写入与查询全部基于 Spring Data MongoDB 的MongoOperations:
- 写入:
saveInternal(CasEvent event)调用mongoTemplate.save(event.assignIdIfNecessary(), collectionName),先为事件分配 ID(若未设置则取System.currentTimeMillis(),见 CasEvent.assignIdIfNecessary),再写入指定集合。 - 清空:
removeAll()使用mongoTemplate.remove(new Query(), CasEvent.class, collectionName)删除集合内全部事件。 - 读取:
load()使用mongoTemplate.stream(...)以流式方式读取全部事件;load(ZonedDateTime)则在查询条件中追加creationTime >= dateTime.toInstant()的时间过滤。
二、配置参数详解(cas.events.mongo.*)
模块的全部配置项统一挂在cas.events.mongo前缀之下,对应的配置模型是 MongoDbEventsProperties,它继承自SingleCollectionMongoDbProperties与BaseMongoDbProperties。注意该属性类上的@RequiresModule(name = "cas-server-support-events-mongo")注解:未引入对应模块时,这些配置不会生效。
2.1 集合相关配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
cas.events.mongo.collection | MongoDbCasEventRepository | MongoDB 中存放认证事件的集合名称。构造函数中通过setCollection("MongoDbCasEventRepository")预置,可覆盖 |
cas.events.mongo.drop-collection | false | 启动时是否先删除(drop)再重新创建集合。测试场景或需要清空历史数据时设为true |
集合的创建发生在 CasMongoDbEventsAutoConfiguration#mongoEventsTemplate:MongoDbConnectionFactory.createCollection(mongoTemplate, mongo.getCollection(), mongo.isDropCollection())会在应用启动装配模板时按需创建集合。
2.2 连接相关配置
以下参数定义在 BaseMongoDbProperties 中,是 MongoDB 连接的基础设置:
| 配置项 | 默认值 | 说明 |
|---|---|---|
cas.events.mongo.client-uri | 空 | MongoDB 连接 URI,形如mongodb://user:psw@ds135522.somewhere.com:35522/db。一旦指定将接管其他连接设置(优先级最高) |
cas.events.mongo.host | localhost | MongoDB 主机地址。多个地址用逗号分隔;若每个主机都自带端口,则端口以此为准 |
cas.events.mongo.port | 27017 | MongoDB 端口 |
cas.events.mongo.user-id | 空 | MongoDB 认证用户名 |
cas.events.mongo.password | 空 | MongoDB 认证密码 |
cas.events.mongo.database-name | 空 | MongoDB 数据库实例名(事件写入的目标数据库) |
cas.events.mongo.authentication-database-name | 空 | 用于认证的数据库名称 |
cas.events.mongo.timeout | PT5S | 连接超时,ISO-8601 时长格式,如PT5S表示 5 秒 |
cas.events.mongo.write-concern | ACKNOWLEDGED | 写关注级别,描述 MongoDB 对写操作要求确认的程度 |
cas.events.mongo.read-concern | AVAILABLE | 读关注级别,可选LOCAL、MAJORITY、LINEARIZABLE、SNAPSHOT、AVAILABLE |
cas.events.mongo.read-preference | PRIMARY | 读偏好,可选PRIMARY、SECONDARY、SECONDARY_PREFERRED、PRIMARY_PREFERRED、NEAREST |
cas.events.mongo.retry-writes | false | 写操作因网络错误失败时是否自动重试 |
cas.events.mongo.ssl-enabled | false | 连接是否启用 SSL |
cas.events.mongo.replica-set | 空 | 副本集名称。副本集提供冗余与高可用,是生产部署的基础 |
此外,连接池相关参数由嵌套属性cas.events.mongo.pool.*提供(MongoDbConnectionPoolProperties),用于控制连接池大小、等待时间等。
2.3 完整配置示例(YAML)
cas: events: mongo: client-uri: mongodb://cas:secret@mongodb.example.org:27017/cas-events # 或使用分散参数: # host: localhost # port: 27017 # user-id: cas # password: secret # authentication-database-name: admin database-name: events collection: MongoDbCasEventRepository drop-collection: false timeout: PT5S write-concern: ACKNOWLEDGED read-concern: AVAILABLE read-preference: PRIMARY retry-writes: false ssl-enabled: false以上配置与仓库测试用例 MongoDbCasEventRepositoryTests 中使用的参数一一对应,可作为最小可运行配置的参考:
cas.events.mongo.user-id=root cas.events.mongo.password=secret cas.events.mongo.host=localhost cas.events.mongo.port=27017 cas.events.mongo.authentication-database-name=admin cas.events.mongo.database-name=events cas.events.mongo.drop-collection=true测试类还标注了@EnabledIfListeningOnPort(port = 27017),即只有在本地27017端口存在 MongoDB 实例时才会执行,这提示了该功能的运行前置条件:必须有一个可连接的 MongoDB 实例。
三、事件数据模型:MongoDB 集合中的文档结构
写入 MongoDB 的事件文档对应 CasEvent 实体(位于api/cas-server-core-api-events模块),其字段结构如下:
| JSON 字段 | 类型 | 说明 |
|---|---|---|
id | long | 事件唯一标识,写入时若小于等于 0 则以System.currentTimeMillis()填充 |
type | String | 事件类型,如CasAuthenticationTransactionSuccessfulEvent、CasAuthenticationTransactionFailureEvent等,非空 |
principalId | String | 与该事件关联的用户主体 ID,非空 |
creationTime | Instant | 事件创建时间,非空 |
properties | Map<String, String> | 事件扩展属性键值对,单值最长 4000 字符 |
properties映射中常见的语义字段通过常量定义:
timestamp:事件时间戳(毫秒);eventId:事件 ID;clientip/serverip:客户端 / 服务端 IP;agent:用户代理(浏览器/设备信息);tenant:多租户场景下的租户标识;geoLatitude、geoLongitude、geoAccuracy、geoTimestamp、geoAddress:地理位置相关(putGeoLocation统一写入);deviceFingerprint:设备指纹。
这些扩展属性通过put(...)链式方法写入(空值会被移除),事件创建方(如认证成功/失败监听器)在发布事件前会填充 IP、Agent、地理位置等信息,MongoDB 仓库会将这些字段原样保存在文档的properties内嵌对象中。
3.1 查询字段与索引语义
MongoDbCasEventRepository 在查询时使用以下三个顶层字段构造Criteria:
creationTime:时间范围过滤,gte(dateTime.toInstant());type:事件类型精确匹配;principalId:主体 ID 精确匹配。
仓库提供了 8 种查询组合(按类型、按主体、按时间及其任意组合),全部返回Stream<? extends CasEvent>流式结果。若需要在大数据量下保证查询性能,可以考虑在 MongoDB 中为creationTime、type、principalId建立合适的索引。
值得注意的是,基类 AbstractCasEventRepository 中带时间参数的查询默认采用内存过滤(load().filter(...)),而 MongoDB 实现则全部下推到数据库端执行(见MongoDbCasEventRepository中对load(ZonedDateTime)、getEventsOfType(type, dateTime)等方法的覆写),因此在大数据量场景下 MongoDB 后端的查询效率更高。
四、保存流程:从事件发布到落库
CAS 的认证事件遵循"发布-订阅"模型。事件被发布后,casEventRepository的save(...)方法被调用,其流程定义在 AbstractCasEventRepository#save 中:
- 调用
eventRepositoryFilter.shouldSaveEvent(event)判断该事件是否需要持久化(默认过滤器为noOp(),即全部保存,见 CasMongoDbEventsAutoConfiguration#mongoEventRepositoryFilter); - 通过则调用子类实现的
saveInternal(event),即MongoDbCasEventRepository.saveInternal,将事件保存进 MongoDB 集合; - 保存成功后,若配置了
ApplicationEventPublisher,还会额外发布一个 Spring Boot Actuator 的AuditApplicationEvent(审计事件),其属性中包含CasEventRepository.PARAM_SOURCE = "CAS",从而与 CAS 的审计机制打通。
五、通过 Actuator 端点查询与管理事件
认证事件持久化到 MongoDB 后,可通过 CAS 的 Actuator 管理端点events进行查询与管理,该端点定义在 CasEventsReportEndpoint 中(端点 ID 为events,默认访问权限为Access.NONE,需显式开放):
GET /actuator/events?limit=1000:以 JSON 数组形式返回事件列表,按timestamp倒序排列,默认最多 1000 条;GET /actuator/events/aggregate:以 NDJSON 流式返回聚合事件报表;DELETE /actuator/events:清空事件仓库(对应MongoDbCasEventRepository.removeAll());POST /actuator/events:导入单个事件(请求体为CasEventJSON)或上传 ZIP 压缩包(包内为多个.json事件文件)批量导入。
通过该端点可以直观验证 MongoDB 后端是否正常工作:写入几条认证事件后访问GET /actuator/events,应能看到来自 MongoDB 集合的完整事件数据。
六、快速验证与测试
仓库自带的集成测试 MongoDbCasEventRepositoryTests 继承自AbstractCasEventRepositoryTests,覆盖了事件保存、按类型/主体/时间查询、清空等全部仓库接口行为。若要在本地复现,需要:
- 在
localhost:27017启动 MongoDB 实例(测试通过@EnabledIfListeningOnPort(port = 27017)检测端口); - 准备测试库
events及认证账号(测试用例使用root/secret,认证库admin); - 运行该测试类,观察
CasMongoDbEventsAutoConfiguration的装配与增删查改流程。
该测试同时验证了drop-collection=true的行为:每次启动都会先 drop 集合再重建,适用于开发调试;生产环境建议保持false,避免启动时误清历史事件数据。
七、小结与使用建议
- 模块先行:使用前必须在构建中引入
cas-server-support-events-mongo,否则cas.events.mongo.*配置不会生效; - 连接配置:推荐直接使用
client-uri完成连接,其余参数作为精细化兜底;database-name决定事件写入哪个库,collection决定写入哪个集合(默认MongoDbCasEventRepository); - 生产建议:保持
drop-collection: false;按type、principalId、creationTime的查询模式为集合建立索引;结合eventsActuator 端点做日常巡检; - 生态定位:该模块是 CAS 事件仓库的 MongoDB 后端实现之一,与 JDBC、Redis、DynamoDb、Kafka 等后端实现并列(见 api/cas-server-core-api-configuration-model/src/main/java/org/apereo/cas/configuration/model/core/events 下的事件配置模型),选择 MongoDB 可获得 NoSQL 的灵活文档结构与流式读取能力,适合与现有 MongoDB 基础设施复用的部署场景。
- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
相关推荐
Apereo CAS 认证事件 Kafka 发布指南:使用 cas-server-support-events-kafka 将认证事件写入 Kafka Topic
Apereo CAS 认证事件 Kafka 发布指南:使用 cas server support events kafka 将认证事件写入 Kafka Topi
后端认证鉴权单点登录gh_mirrors/cas/cas与GitLab集成:代码仓库的SSO认证实现终极指南
gh_mirrors/cas/cas与GitLab集成:代码仓库的SSO认证实现终极指南 在当今企业级开发环境中, 统一身份认证 已成为提升开发效率和保障代码安
后端认证鉴权单点登录Apereo CAS集成Google Authenticator实现多因素认证指南
Apereo CAS集成Google Authenticator实现多因素认证指南 概述 在当今网络安全环境中,多因素认证 MFA 已成为保护敏感系统的必备措施
后端认证鉴权单点登录
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考