CAS 认证节流 Hazelcast 分布式存储配置指南
2026/9/24 1:56:06 网站建设 项目流程
  • 后端
  • 认证鉴权
  • 单点登录

【免费下载链接】cas

Apereo CAS - Identity & Single Sign On for all earthlings and beyond.

项目地址:https://gitcode.com/gh_mirrors/ca/cas
点击查看免费下载

本篇技术指南讲解 Apereo CAS 中基于 Hazelcast 分布式 Map 实现的认证节流(Authentication Throttling)方案:如何通过启用cas-server-support-throttle-hazelcast模块,让集群中所有 CAS 节点共享同一份"失败认证尝试"记录,从而在多节点部署下统一限制暴力破解与密码猜测行为。读完本文你将掌握该模块的依赖启用方式、cas.authn.throttle.hazelcast全系列配置项(含集群网络与 TLS 加密)、节流速率判定原理,以及从自动配置到后台清理任务的完整源码实现链路。

功能概述:用分布式 Map 记录节流尝试

CAS 的认证节流功能用于限制失败的登录尝试,以对抗密码猜测等滥用场景。官方文档 Configuring-Authentication-Throttling-Hazelcast.md 明确指出:

This feature uses a distributed Hazelcast map to record throttled authentication attempts.

即:该功能使用一张分布式 Hazelcast Map(默认名为ipMap)来记录被节流的认证尝试。与基于单机内存 Map 的方案不同,分布式 Map 让集群内的所有 CAS 节点读写同一份节流数据,任何节点记录的失败尝试都能被其他节点感知,因此特别适合部署在负载均衡之后的多节点 CAS 集群。

该组件同时依赖并需要 CAS 审计功能(见 Audits.md),因为节流事件的记录与审计(inspektr)体系共享同一套事件采集链路,失败尝试会作为审计动作(默认动作码AUTHENTICATION_FAILED)被登记。

启用模块

在配置 overlay(configuration overlay)中添加以下依赖即可启用该模块:

implementation "org.apereo.cas:cas-server-support-throttle-hazelcast"

模块的 Maven 坐标为org.apereo.cas:cas-server-support-throttle-hazelcast。从源码结构看,该模块内部仅有三个类文件,职责高度聚焦:

  • CasHazelcastThrottlingAutoConfiguration:Spring Boot 自动配置入口(CasHazelcastThrottlingAutoConfiguration.java);
  • HazelcastMapThrottledSubmissionsStore:基于 HazelcastIMap的节流记录存储实现(HazelcastMapThrottledSubmissionsStore.java);
  • CasHazelcastThrottlingConfigurationTests:对应的单元测试(CasHazelcastThrottlingConfigurationTests.java)。

模块由特性开关(feature flag)控制:自动配置类标注了@ConditionalOnFeatureEnabled(feature = Throttling, module = "hazelcast"),只有认证节流特性启用且使用 hazelcast 存储时才会装配。

配置详解:cas.authn.throttle.hazelcast

该模块的全部配置统一挂在cas.authn.throttle.hazelcast前缀下,其顶层属性模型为HazelcastThrottleProperties(HazelcastThrottleProperties.java),它直接继承自BaseHazelcastProperties(BaseHazelcastProperties.java),内含两大块:cluster(集群配置)与core(Hazelcast 核心配置)。

Hazelcast 核心配置:cas.authn.throttle.hazelcast.core

对应属性类HazelcastCoreProperties(HazelcastCoreProperties.java):

属性默认值说明
cas.authn.throttle.hazelcast.core.license-keyHazelcast 企业版许可证密钥。启用 WAN 复制、SSL 等企业特性时必需
cas.authn.throttle.hazelcast.core.enable-compressionfalse使用默认 Java 序列化时是否启用压缩
cas.authn.throttle.hazelcast.core.enable-management-center-scriptingtrue是否允许从 Management Center 执行脚本
cas.authn.throttle.hazelcast.core.enable-jettrue是否在 Hazelcast 实例上启用 Jet 服务(分布式批处理/流处理引擎,SQL 服务依赖它)

Hazelcast 集群核心:cas.authn.throttle.hazelcast.cluster.core

对应属性类HazelcastCoreClusterProperties(HazelcastCoreClusterProperties.java),该组配置直接决定节流 Map 的数据分布、备份与驱逐行为:

属性默认值说明
cas.authn.throttle.hazelcast.cluster.core.instance-name无(必填)当前 Hazelcast 实例名称,支持 Spring 表达式语言(@ExpressionLanguageCapable)。测试用例中将其设为throttlehzstore
cas.authn.throttle.hazelcast.cluster.core.async-filluptrue复制模式下新成员加入时是否异步填充:true不阻塞读写但数据渐进可见;false阻塞读写直到填充完成
cas.authn.throttle.hazelcast.cluster.core.replicatedfalse是否使用 Replicated Map(全量复制到所有成员,读快但内存占用高、更新量大时扩展性差)
cas.authn.throttle.hazelcast.cluster.core.partition-member-group-type分区组策略:PER_MEMBERHOST_AWARECUSTOMZONE_AWARESPI
cas.authn.throttle.hazelcast.cluster.core.logging-typeslf4jHazelcast 日志适配:jdklog4jslf4jnone
cas.authn.throttle.hazelcast.cluster.core.max-no-heartbeat-seconds300节点心跳超时秒数,超过则认为节点死亡
cas.authn.throttle.hazelcast.cluster.core.map-merge-policyPUT_IF_ABSENTMap 合并策略:PUT_IF_ABSENTHIGHER_HITSDISCARDPASS_THROUGHEXPIRATION_TIMELATEST_UPDATELATEST_ACCESS
cas.authn.throttle.hazelcast.cluster.core.max-size85Map 最大条目数
cas.authn.throttle.hazelcast.cluster.core.max-size-policyUSED_HEAP_PERCENTAGE上限策略:FREE_HEAP_PERCENTAGEFREE_HEAP_SIZEFREE_NATIVE_MEMORY_PERCENTAGEFREE_NATIVE_MEMORY_SIZEPER_NODEPER_PARTITIONUSED_HEAP_PERCENTAGEUSED_HEAP_SIZEUSED_NATIVE_MEMORY_PERCENTAGEUSED_NATIVE_MEMORY_SIZE
cas.authn.throttle.hazelcast.cluster.core.eviction-policyLRU驱逐策略:LRULFUNONE
cas.authn.throttle.hazelcast.cluster.core.backup-count1同步备份副本数,范围 0~6。设为 0 表示不备份(性能优先)
cas.authn.throttle.hazelcast.cluster.core.async-backup-count0异步备份副本数。异步备份不阻塞主操作
cas.authn.throttle.hazelcast.cluster.core.timeout5TCP/IP 配置与成员加入集群的连接超时(秒)
cas.authn.throttle.hazelcast.cluster.core.cp-member-count0CP 子系统成员数(CP 子系统至少需要 3 个成员)

Hazelcast 集群网络:cas.authn.throttle.hazelcast.cluster.network

对应属性类HazelcastNetworkClusterProperties(HazelcastNetworkClusterProperties.java):

属性默认值说明
cas.authn.throttle.hazelcast.cluster.network.tcpip-enabledtrue是否启用 TCP/IP join 机制。新成员通过连接一个或多个已知成员来获知集群全貌
cas.authn.throttle.hazelcast.cluster.network.members["localhost"]集群已知成员列表,必须包含所有 CAS 节点(含当前节点),可用逗号分隔多个地址,如10.11.12.1,10.11.12.2
cas.authn.throttle.hazelcast.cluster.network.port5701Hazelcast 成员间通信端口
cas.authn.throttle.hazelcast.cluster.network.port-auto-incrementtrue是否允许端口自动递增。设为false可固定单端口(测试用例中即固定为5710
cas.authn.throttle.hazelcast.cluster.network.outbound-ports出站端口定义列表
cas.authn.throttle.hazelcast.cluster.network.local-address服务器 socket 绑定的本机地址覆盖值
cas.authn.throttle.hazelcast.cluster.network.public-address对外广播给其他成员与客户端的公共地址
cas.authn.throttle.hazelcast.cluster.network.network-interfaces允许使用的网卡接口(支持*-范围通配,如10.3.10.*10.3.10.4-18,逗号分隔)
cas.authn.throttle.hazelcast.cluster.network.ipv4-enabledtrue是否仅使用 IPv4 协议栈(部分平台如 AWS 不支持 IPv6,默认关闭 IPv6)

Hazelcast 网络 TLS 加密:cas.authn.throttle.hazelcast.cluster.network.ssl

Hazelcast 支持通过 TLS(Transport Layer Security)协议,配合密钥库(key store)与信任库(trust store)在集群成员之间、以及成员与客户端之间建立端到端的 socket 级加密通信。对应属性类HazelcastNetworkSslProperties(HazelcastNetworkSslProperties.java)。

注意:Hazelcast SSL 属于企业版特性,启用该功能需要合法的 Hazelcast Enterprise License。

CAS 在启用 SSL 后会使用配置的密钥库自动初始化 SSL 上下文,并提供一个默认的 SSL context factory 实现来引导配置。主要属性如下:

属性默认值说明
cas.authn.throttle.hazelcast.cluster.network.ssl.protocolTLSTLS/SSL 协议算法,建议明确版本如TLSv1.2
cas.authn.throttle.hazelcast.cluster.network.ssl.keystore密钥库文件路径(使用双向认证时必需)
cas.authn.throttle.hazelcast.cluster.network.ssl.keystore-password访问密钥库中密钥的口令
cas.authn.throttle.hazelcast.cluster.network.ssl.key-store-typeJKS密钥库类型,常用还有PKCS12
cas.authn.throttle.hazelcast.cluster.network.ssl.trust-store信任库文件路径(存放受信任证书集合)
cas.authn.throttle.hazelcast.cluster.network.ssl.trust-store-typeJKS信任库类型
cas.authn.throttle.hazelcast.cluster.network.ssl.trust-store-password解锁信任库的口令
cas.authn.throttle.hazelcast.cluster.network.ssl.mutual-authentication双向认证:REQUIRED(强制客户端证书)或OPTIONAL(请求但不强制)
cas.authn.throttle.hazelcast.cluster.network.ssl.cipher-suitesJVM 全部支持套件允许使用的密码套件,逗号分隔
cas.authn.throttle.hazelcast.cluster.network.ssl.trust-manager-algorithm/key-manager-algorithm提供信任管理器 / 认证密钥的算法名称

Linux 熵源性能提示:在 Linux 下,JVM 默认使用/dev/random生成随机数。如果系统熵不足以跟上随机数的消耗速率,加解密可能阻塞长达数分钟。可通过设置系统属性-Djava.security.egd=file:/dev/./urandom缓解。需要注意:若熵确实不足,该选项不会阻塞,返回的随机值理论上可能更容易遭受密码学攻击,因此应权衡使用。

与节流核心配置联动

Hazelcast 存储只是节流记录的载体,节流的判定策略仍由cas.authn.throttle下的核心配置决定(属性模型见 ThrottleProperties.java):

失败判定:cas.authn.throttle.failure

对应ThrottleFailureProperties(ThrottleFailureProperties.java):

属性默认值说明
cas.authn.throttle.failure.codeAUTHENTICATION_FAILED记录到审计日志的失败动作码,标识认证失败事件
cas.authn.throttle.failure.threshold-1阈值内的失败登录次数
cas.authn.throttle.failure.range-seconds-1阈值对应的时间区间(秒)
cas.authn.throttle.failure.throttle-window-seconds0账号保持锁定/节流状态的秒数,超过该时间后释放。不设置则按失败阈值与速率计算

阈值速率(Threshold Rate):失败阈值速率按threshold / rangeSeconds计算。例如threshold=1rangeSeconds=3时速率为0.333333。一次认证请求是否被节流,取决于该请求的提交速率(当前时间与上一次提交时间的差值的倒数)是否超过失败阈值速率——超过 1 次/3 秒的失败速率通常被视为自动化认证尝试,是制定节流策略的合理依据。无论策略如何,都需在安全与可用性之间权衡,过于严格可能阻止合法认证。

核心与调度:cas.authn.throttle.core / cas.authn.throttle.schedule

  • cas.authn.throttle.core(ThrottleCoreProperties.java):username-parameter(从请求中提取用户名的参数名)、header-name(从请求头提取值的头名)、app-code(审计日志中的应用标识,默认CAS)。
  • cas.authn.throttle.schedule(SchedulingProperties.java):节流记录的后台清理任务。ThrottleProperties构造器中将其默认设为enabled=truestart-delay=PT10Srepeat-interval=PT30S。可选cron-expressioncron-time-zone;当使用 cron 表达式时必须将 start delay 与 repeat interval 置空。该调度周期直接决定了 Hazelcast 节流 Map 中记录的最大空闲存活时长(见下文源码分析)。

源码级实现原理

自动配置与ipMap的创建

CasHazelcastThrottlingAutoConfiguration.java 是模块装配的入口,其核心逻辑:

  1. 定义常量MAP_KEY = "ipMap"作为分布式 Map 的名字;
  2. 通过@Qualifier("casTicketRegistryHazelcastInstance")注入 CAS 已有的 Hazelcast 实例(该实例同时服务于 ticket registry,体现复用同一集群的部署思路);
  3. cas.authn.throttle.schedule.repeat-interval解析为秒,作为 Map 条目的最大空闲时间(maxIdleSeconds);
  4. 调用HazelcastConfigurationFactory.buildMapConfig(hz, MAP_KEY, timeout)构建 Map 配置并注册到 HazelcastConfig
  5. 返回HazelcastMapThrottledSubmissionsStore,以throttleSubmissionStore为 bean 名装配。

Map 配置的构建细节在 HazelcastConfigurationFactory.buildMapConfig 中可见:默认(非 replicated)情况下会生成标准MapConfig,应用maxSizePolicymaxSizeevictionPolicybackupCountasyncBackupCountmapMergePolicy等集群核心配置,设置maxIdleSeconds为节流调度周期,并使用二进制内存格式(InMemoryFormat.BINARY);若replicated=true则生成ReplicatedMapConfig并应用asyncFillup

节流记录的存储与判定

HazelcastMapThrottledSubmissionsStore(HazelcastMapThrottledSubmissionsStore.java)继承自 BaseMappableThrottledSubmissionsStore.java,后者实现了接口 ThrottledSubmissionsStore.java 的putgetcontainsremoveclearentriesexceedsThresholdrelease等方法。其核心判定逻辑:

  • 提交速率submissionRate = 1000.0 / (now - entry),即两次提交时间差的毫秒数换算为"次/秒";
  • 超阈值判定exceedsThreshold比较当前提交速率与阈值速率,若前者大于后者则请求将被节流;
  • 释放逻辑release会逐条检查——已过期的直接删除;仍在expiration窗口内的保留;提交速率低于阈值速率的记录被释放删除。

Hazelcast 实现唯一重写的方法是removeIf:它将底层Map强转为IMap,使用hzMap.removeAll(Predicate)将条件判断下推至 Hazelcast 集群执行,而不是在本地迭代删除,从而保证多节点数据一致性。

单条节流记录的数据结构ThrottledSubmission(ThrottledSubmission.java)包含idkey(IP 或 IP+用户名)、value(UTC 提交时间)、usernameclientIpAddressexpiration,并提供hasExpiredAlready()isStillInExpirationWindow()两个过期判断方法。

请求拦截与后台清理

节流的触发位于认证请求拦截器链中:AbstractInMemoryThrottledSubmissionHandlerInterceptorAdapter(AbstractInMemoryThrottledSubmissionHandlerInterceptorAdapter.java)在认证失败时构造ThrottledSubmissionput进存储;在请求进入时先检查该 key 是否仍在节流窗口内、再调用exceedsThreshold判定是否需要拦截;release()则委托给存储的release(thresholdRate)

后台清理由 InMemoryThrottledSubmissionCleaner.java 驱动,其@Scheduled注解的默认值为initialDelayString=PT10SfixedDelayString=PT15S,可通过cas.authn.throttle.schedule.*覆盖;每次运行会遍历所有ThrottledSubmissionHandlerInterceptor并调用release(),从而周期性地从 Hazelcast Map 中淘汰过期与可释放的记录。

验证与测试

模块自带集成测试 CasHazelcastThrottlingConfigurationTests.java,它同时加载了 Hazelcast Ticket Registry 自动配置与本模块自动配置,并以真实属性启动:

cas.authn.throttle.hazelcast.cluster.network.port-auto-increment=false cas.authn.throttle.hazelcast.cluster.network.port=5710 cas.authn.throttle.hazelcast.cluster.core.instance-name=throttlehzstore

测试流程完整覆盖存储生命周期:注入throttleSubmissionStorebean →put一条记录 →get断言可读取 → 断言entries().count()非零 →removeIf按条件删除 →remove按 key 删除 → 断言条目数为 0。该测试验证了ThrottledSubmissionsStore各操作在 Hazelcast 后端下的正确行为,可作为自定义扩展时的参考模板。

高可用与多节点部署注意事项

根据 Configuring-Authentication-Throttling-Failure.md 的说明,CAS 的节流组件适用于满足推荐 HA 架构的部署场景:

  • 负载均衡启用**会话亲和(session affinity)**时,内存版组件可用:亲和性按源 IP 路由,来自固定位置的攻击者会绑定到同一 CAS 节点,节流记录因此完整;
  • 分布式攻击(请求被不确定地路由到不同节点)会让内存版组件记录分散,且攻击源本身多变,精确统计本就无意义——节流组件假定恒定源 IP 才能有效跟踪;
  • 关键结论:登录节流组件不足以检测或阻止分布式密码暴力破解,无论使用内存还是 Hazelcast 存储都应配合其他防护手段。

选用 Hazelcast 存储的核心收益在于:当集群较大、会话亲和无法严格保证时,ipMap的分布式特性让所有节点共享同一份失败记录,节流判定不再依赖请求是否命中同一节点,从而在保证一致性的同时简化运维对路由策略的依赖。配置时请务必正确维护cluster.network.members列表(包含全部 CAS 节点)并确保cluster.network.port在各节点间可达;若启用 TLS 加密,还需为所有节点配置一致的信任库并准备 Hazelcast Enterprise License。

  • 后端
  • 认证鉴权
  • 单点登录

【免费下载链接】cas

Apereo CAS - Identity & Single Sign On for all earthlings and beyond.

项目地址:https://gitcode.com/gh_mirrors/ca/cas
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询