资讯动态

CAS 使用 MongoDB 持久化 Google Authenticator 注册信息与 OTP 令牌

发布时间:2026/10/15 20:00:27 来源:尧图企业网站定制
后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载MongoDB 是 Apereo CAS 中 Google AuthenticatorTOTP多因素认证的官方存储后端之一用于保存用户的设备注册记录一次性密码账户凭证以及用于防重放的 OTP 令牌。本文基于cas-server-support-gauth-mongo模块系统讲解如何引入依赖、配置 MongoDB 连接与集合、理解用户名排序规则collation索引的底层原理以及令牌仓库的过期清理机制帮助你在生产环境中将 Google Authenticator 的注册数据与令牌安全地落入 MongoDB。一、功能定位哪两类数据需要落库在使用 Google Authenticator 作为第二因素时CAS 需要持久化两类数据而cas-server-support-gauth-mongo模块恰好覆盖了它们数据类别存储仓库实现说明设备注册记录账号凭证MongoDbGoogleAuthenticatorTokenCredentialRepository每个用户与其绑定的 Authenticator 设备密钥、验证码、备用 scratch codes对应集合默认名为MongoDbGoogleAuthenticatorRepositoryOTP 一次性令牌GoogleAuthenticatorMongoDbTokenRepository已使用/已签发的一次性验证码记录用于防止重放攻击对应集合默认名为MongoDbGoogleAuthenticatorTokenRepository注册记录仓库MongoDbGoogleAuthenticatorTokenCredentialRepository.java令牌仓库GoogleAuthenticatorMongoDbTokenRepository.java两个仓库均通过 Spring Data MongoDB 的MongoOperations操作数据并由自动配置类 CasGoogleAuthenticatorMongoDbAutoConfiguration.java 统一装配。二、引入模块依赖在 CAS 项目中加入以下模块对应 Maven/Gradle 坐标org.apereo.cas:cas-server-support-gauth-mongoimplementation org.apereo.cas:cas-server-support-gauth-mongo:${projectVersion}从配置模型来看该模块通过RequiresModule(name cas-server-support-gauth-mongo)声明其依赖关系见 MongoDbGoogleAuthenticatorMultifactorProperties.java同时底层依赖cas-server-support-mongo-core提供 MongoDB 连接工厂能力。模块仅在满足以下条件时才会激活见 自动配置类功能开关GoogleAuthenticator处于启用状态模块标识为mongo。三、配置 MongoDB 连接与集合所有配置项位于cas.authn.mfa.gauth.mongo.*命名空间下。以下是一份完整的配置示例# --- MongoDB 连接基础信息 --- cas.authn.mfa.gauth.mongo.client-urimongodb://user:pswds135522.somewhere.com:35522/gauthdb cas.authn.mfa.gauth.mongo.hostlocalhost cas.authn.mfa.gauth.mongo.port27017 cas.authn.mfa.gauth.mongo.user-idroot cas.authn.mfa.gauth.mongo.passwordsecret cas.authn.mfa.gauth.mongo.database-namegauthdb cas.authn.mfa.gauth.mongo.authentication-database-nameadmin # --- 连接行为 --- cas.authn.mfa.gauth.mongo.timeoutPT5S cas.authn.mfa.gauth.mongo.write-concernACKNOWLEDGED cas.authn.mfa.gauth.mongo.read-concernAVAILABLE cas.authn.mfa.gauth.mongo.read-preferencePRIMARY cas.authn.mfa.gauth.mongo.retry-writesfalse cas.authn.mfa.gauth.mongo.ssl-enabledfalse cas.authn.mfa.gauth.mongo.replica-set # --- 集合名与初始化行为 --- cas.authn.mfa.gauth.mongo.collectionMongoDbGoogleAuthenticatorRepository cas.authn.mfa.gauth.mongo.token-collectionMongoDbGoogleAuthenticatorTokenRepository cas.authn.mfa.gauth.mongo.drop-collectionfalse # --- Google Authenticator 核心参数可选 --- cas.authn.mfa.gauth.core.issuerCASIssuer cas.authn.mfa.gauth.core.labelCASLabel cas.authn.mfa.gauth.core.code-digits6 cas.authn.mfa.gauth.core.time-step-size30 cas.authn.mfa.gauth.core.window-size33.1 连接参数详解连接参数继承自 BaseMongoDbProperties.java关键项包括client-uri完整连接 URI形如mongodb://user:pswds135522.somewhere.com:35522/db。一旦设置将优先于其余独立连接参数生效host/port单机连接地址默认localhost:27017host支持逗号分隔多个地址多主机时假定每个地址自带端口user-id/password认证凭据database-name目标数据库实例名必填authentication-database-name用于认证的数据库名timeout连接超时默认PT5SISO-8601 时长格式write-concern写入确认级别默认ACKNOWLEDGEDread-concern读取关注级别可取值LOCAL、MAJORITY、LINEARIZABLE、SNAPSHOT、AVAILABLE默认AVAILABLEread-preference读取偏好可取值PRIMARY、SECONDARY、SECONDARY_PREFERRED、PRIMARY_PREFERRED、NEAREST默认PRIMARYretry-writes网络错误时是否重试写入ssl-enabled是否启用 SSL 连接replica-set副本集名称用于高可用部署。3.2 集合参数详解集合相关参数定义在 MongoDbGoogleAuthenticatorMultifactorProperties.java 与其父类 SingleCollectionMongoDbProperties.javacollection设备注册记录账号凭证集合名默认MongoDbGoogleAuthenticatorRepositorytoken-collectionOTP 令牌集合名默认MongoDbGoogleAuthenticatorTokenRepository用于防重放drop-collection启动时是否先删除集合再重建默认false。测试环境常用true保证干净的初始状态生产环境务必保持false以免数据丢失。在自动配置中mongoDbGoogleAuthenticatorTemplateBean 会在构建MongoTemplate时调用MongoDbConnectionFactory.createCollection(...)确保令牌集合存在见 自动配置类。四、用户名匹配与 collation 索引忽略大小写、保留重音这是本模块最值得注意的细节用户名匹配忽略大小写但不忽略重音accents。例如jose与JOSE视为同一用户而jose与josé视为不同用户。实现方式是在 MongoDB 查询中显式携带 collation排序规则。注册记录仓库使用固定规则见 MongoDbGoogleAuthenticatorTokenCredentialRepository.javaprivate static final Collation USERNAME_COLLATION Collation.of(Locale.ENGLISH).strength(Collation.ComparisonLevel.secondary());使用Locale.ENGLISHen作为区域强度取secondary忽略大小写差异但保留重音差异若取primary则会连重音一并忽略导致jose与josé共用设备这是刻意避免的注释中同时说明之所以仍忽略大小写是为了兼容历史文档——早期未将用户名统一小写存储可能残留混合大小写的记录。4.1 启动时自动创建username_collated索引MongoDB 的规则是带 collation 的查询只能命中同样 collation 的索引。因此CAS 在启动时会为username字段创建一枚名为username_collated的升序索引并绑定同一 collation从而让按用户名查询走索引而非全集合扫描见 createIndexes()val index new Index() .on(username, Sort.Direction.ASC) .named(USERNAME_INDEX_NAME) // username_collated .collation(USERNAME_COLLATION); try { mongoTemplate.indexOps(collectionName).createIndex(index); } catch (final Exception e) { LOGGER.warn(Unable to create index [{}] on collection [{}]: [{}], USERNAME_INDEX_NAME, collectionName, e.getMessage()); }要点索引名称固定为username_collated与普通 username 索引区分开创建已存在且选项一致的索引是幂等操作不会产生副作用如果创建失败例如 MongoDB 账号权限不足CAS 仅记录 warning 日志不会中断启动此时按用户名查询退化为全集合扫描功能仍可用只是性能下降按id查询走 MongoDB 内置的_id索引不携带 collation无需额外处理。该行为在单元测试中有直接验证。测试 MongoDbGoogleAuthenticatorTokenCredentialRepositoryTests.java 断言registry.save(registry.create(jose suffix)); assertEquals(1, registry.count(JOSE suffix)); // 忽略大小写命中 assertEquals(0, registry.count(jos\u00e9 suffix)); // 保留重音不命中 // 索引存在且 collation 为 secondary / en assertEquals(2, ((Number) index.getCollation().orElseThrow().get(strength)).intValue()); assertEquals(en, index.getCollation().orElseThrow().get(locale));五、令牌仓库防重放与过期清理GoogleAuthenticatorMongoDbTokenRepository负责在认证过程中记录已签发/已使用的 OTP防止同一验证码被重复提交见 GoogleAuthenticatorMongoDbTokenRepository.java。写入store(token)保存令牌文档字段包括userId、token验证码与issuedDateTime签发时间读取与删除按userId与验证码组合查询或删除同样携带 collation令牌仓库使用primary强度即完全忽略大小写与重音差异计数count(uid)用于统计某用户已生成的令牌数认证流程据此判断验证码是否已被使用。过期清理由cleanInternal()完成删除所有issuedDateTime早于「当前时间减去expireTokensInSeconds」的记录query.addCriteria(Criteria.where(issuedDateTime) .gte(LocalDateTime.now(ZoneId.systemDefault()) .minusSeconds(this.expireTokensInSeconds))); this.mongoTemplate.remove(query, GoogleAuthenticatorToken.class, this.collectionName);其中expireTokensInSeconds取自cas.authn.mfa.gauth.core.time-step-sizeTOTP 时间步长默认 30 秒即令牌的有效窗口。清理动作由 CAS 内部的调度任务周期性触发cas.authn.mfa.gauth.cleaner.schedule.*可控制开关、启动延迟与执行间隔默认启动延迟与重复间隔均为PT1M。六、数据加解密可选注册记录仓库还支持对敏感字段如设备密钥、scratch codes进行加解密相关 Bean 为googleAuthenticatorAccountCipherExecutor与googleAuthenticatorScratchCodesCipherExecutor通过cas.authn.mfa.gauth.crypto.*配置。测试用例中以cas.authn.mfa.gauth.crypto.enabledfalse关闭加密以简化验证生产环境建议启用并为加密/签名分别配置 32 字节的 key配置模型默认encryption.key-size与signing.key-size均为 256 位字符串密钥。仓库内的encode(account)/decode(account)继承自BaseGoogleAuthenticatorTokenCredentialRepository负责在写入前加密、读取后解密scratch codes 使用独立的CipherExecutorNumber, Number处理。七、完整落地清单引入依赖添加cas-server-support-gauth-mongo确保cas-server-support-gauthGoogle Authenticator 核心模块已就位配置连接设置cas.authn.mfa.gauth.mongo.host/port或client-uri以及database-name、user-id、password需要时含authentication-database-name确认集合名默认注册集合MongoDbGoogleAuthenticatorRepository、令牌集合MongoDbGoogleAuthenticatorTokenRepository生产环境不要开启drop-collection确认索引权限保证运行 CAS 的 MongoDB 账号具备在目标集合创建索引的权限以自动建立username_collated索引无权限时 CAS 会告警但功能不受影响确认调度清理保持cas.authn.mfa.gauth.cleaner.schedule.enabledtrue默认开启让过期令牌被定期清除避免集合无限增长验证行为可参考模块测试用例 MongoDbGoogleAuthenticatorTokenCredentialRepositoryTests.java 与 GoogleAuthenticatorMongoDbTokenRepositoryTests.java二者均要求本机27017端口存在 MongoDB 实例来验证大小写/重音匹配语义与索引创建逻辑。通过以上步骤你可以让 CAS 的 Google Authenticator 设备注册与 OTP 令牌全部持久化到 MongoDB享受集合索引带来的高效查询同时保留可审计、可备份的运维能力。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS 接入指南使用 JPA 持久化 Google AuthenticatorTOTP注册记录与令牌Apereo CAS 接入指南使用 JPA 持久化 Google AuthenticatorTOTP注册记录与令牌 导读 Apereo CAS 默认自带的后端认证鉴权单点登录CAS 6.5 集成 DynamoDb 存储 Google AuthenticatorTOTP注册记录与一次性令牌CAS 6.5 集成 DynamoDb 存储 Google AuthenticatorTOTP注册记录与一次性令牌 Apereo CAS 的 Google后端认证鉴权单点登录Apereo CAS 实战将 FIDO2 WebAuthn 多因素设备注册持久化到 MongoDBApereo CAS 实战将 FIDO2 WebAuthn 多因素设备注册持久化到 MongoDB 本篇技术指南聚焦 Apereo CAS 中 FIDO2 W后端认证鉴权单点登录上一篇DINOv3零样本分割技术深度解析dino.txt架构设计与实现原理下一篇i3窗口堆叠与标签页切换高效组织多窗口的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑