从源代码分析CAS的Session过期时间配置

CAS 文档的 Ticket Expiration Policies 章节中描述了 TGC 的过期策略,可是在实际配置的时候还是会遇到过期策略行为与配置不太相符的问题。本文结合源代码,对 CAS 的过期策略配置进行准确的描述,希望能够帮助到各位。

CAS 的所有配置项在运行时会由 Spring 的配置解析功能 (https://www.baeldung.com/spring-enable-config-properties)解析到 CasConfigurationProperties 类。由这个类的源代码,我们可以看到这个类的每个成员的命名都对应了 CAS Properties 配置项中的一个子项。TGT 的配置对应的是org.apereo.cas.configuration.model.core.ticket.TicketGrantingTicketProperties。通过 IDEA 的 Find Usages 的功能,我们来查找一下该类中 hardTimeout 成员的引用,发现其实 CAS 是在 CasCoreTicketsConfiguration 这个类中初始化 Ticket 的 ExpirationPolicy 的。

一般策略

我们将目光锁定在 ticketGrantingTicketExpirationPolicy 这个函数上,可以得出以下结论:

  1. 如果把 cas.ticket.tgt.maxTimeToLiveInSecondscas.ticket.tgt.timeToKillInSeconds都配置为小于零,则 TGT 不会过期;
  2. 在上述两个配置项都大于零的情况下(如果不在 cas.properties 中特殊配置,那默认就是大于零的,默认值可以看代码),检查 cas.ticket.tgt.timeout.maxTimeToLiveInSeconds ,如果该配置大于零,则使用 TimeoutExpirationPolicy (当用户 cas.ticket.tgt.timeout.maxTimeToLiveInSeconds 秒没有使用该 TGT 时,则 TGT 过期,如果用户一直使用,则理论上可以永远不过期)
  3. 如果不满足 TimeoutExpirationPolicy 的启用条件,那么就检查 Throttled Timeout 的启用条件,这个没啥好说的;
  4. 然后是 Hard Timeout,如果 cas.ticket.tgt.hardTimeout.timeToKillInSeconds 大于零,则使用 Hard Timeout,意思是不论用户使用多少次,什么时候使用,TGT 都在指定的时间后失效
  5. 最后是 TicketGrantingTicketExpirationPolicy ,这是 Hard Timeout 与 TimeoutExpirationPolicy 的组合。

如果你什么都没有配置,那我们可以由默认值知道 CAS 默认的 TGT 过期策略是:如果用户登录后两次使用这个 TGT 颁发 ST 的时间间隔超过了 7200 秒,那么这个 TGT 就会过期;就算用户一直使用这个 TGT,那这个 TGT 也会在从登录那一刻开始算起的 28800 秒(8小时)后过期。

在配置的时候需要注意,maxTimeToLiveInSecondstimeToKillInSeconds 有好几个,不要搞混。而且配置了其中一种策略之后就不要配置其他的策略,否则容易因为优先级的问题导致无法配置为预期的行为,因为这些策略的配置不能自由组合。

cas.ticket.tgt.rememberMe.enabled 配置为 false 时,TGT 的过期时间到此就可以确定了。而且此时登录界面上的 Remember Me 选项不会显示,CAS 种下的 TGC 的 Cookie Expiration 是 Session ,只要用户关闭浏览器,这个 Cookie 就会被浏览器忘记,下次通过 CAS 登录其他服务时就需要一个新的 TGT,所以就需要重新输入一次凭据。

Remember Me 策略

除非显示配置 cas.ticket.tgt.rememberMe.enabledfalse ,否则 Remember Me 功能在 CAS 中是默认被启用的。如果启用了 Remember Me,会使得在用户勾选了"Remember Me"的情况下上述的配置全部失效,这也是 CAS 配置中的一个坑。

我们来看 CasCoreTicketsConfiguration 中的 grantingTicketExpirationPolicy ,这是一个具有 @ConditionalOnMissingBean(name = "grantingTicketExpirationPolicy") annotation 的 Bean,CAS 最终使用了这个 Bean 作为 TGT 的过期策略,原因是在 230行 处,这个 Bean 最终被传入了 DefaultTicketGrantingTicketFactory 。继续阅读源代码,可以知道当 cas.ticket.tgt.rememberMe.enabledtrue 时,会启用 RememberMeDelegatingExpirationPolicy

RememberMeDelegatingExpirationPolicy 的作用是当用户选择 "Remember Me" 选项时,使用一个写死的 HardTimeoutExpirationPolicy ,过期时间通过 cas.ticket.tgt.rememberMe.timeToKillInSeconds 设置;当用户没有勾选 "Remember Me" 时,则使用上方配置的一般策略。

结论

CAS 提供几种不同的 TGT Expiration Policy,但是在配置时需要注意这几种 Policy 不能自由组合,而且当用户勾选了 Remember Me 时,Expiration Policy 会被设置为 HardTimeout。

此条目发表在折腾 CAS, 搬砖杂记分类目录,贴了, 标签。将固定链接加入收藏夹。

发表评论

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据