CAS5.3X 之配置RememberMe & Cookie Secure属性影响

CAS5.3X 之配置RememberMe

  • 前言
  • CAS 5.3X 之RememberMe
    • 分析实现
    • RememberMe 之 TGC
    • 思考:是什么导致了TGC没有被写入cookie呢?
  • 总结
    • 问题原因
    • 解决

前言

今儿老大突然说我CAS项目的代码有问题,心态突然很慌,咋滴了又,都运行两年了,现在才出问题?

然后开始了捡起两年前代码的惊叹之路,连连感叹,这我写的啊?
嗯嗯,话不多说。。。

CAS 5.3X 之RememberMe

在前台加入以下代码:

   <section class="form-check" th:if="${rememberMeAuthenticationEnabled}">
   <p>
   <input type="checkbox" name="rememberMe" id="rememberMe" value="true" tabindex="5"/>
       <label for="rememberMe" th:text="#{screen.rememberme.checkbox.title}">Remember Melabel>
   p>
   section>

application.properties添加配置:

#记住我
cas.ticket.tgt.rememberMe.enabled=true
cas.ticket.tgt.rememberMe.timeToKillInSeconds=3600

咋一看,代码没问题啊,配置也没问题,流程初始化的配置也没问题的呀。
但测试反应给我的问题是,没有实现记住我的功能,无法在浏览器关闭掉重新访问时跳转到正确的客户端地址。

哎,先分析…

分析实现

大伙都知道,CAS的核心就是其Ticket,及其在Ticket之上的一系列处理操作。CAS的主要票据有TGT、ST、PGT、PGTIOU、PT,其中TGT、ST是CAS1.0(基础模式)协议中就有的票据,PGT、PGTIOU、PT是CAS2.0(代理模式)协议中有的票据。这里主要介绍CAS1.0—基础模式中的几种票据。

  • TGT(Ticket Grangting Ticket)

TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后,生成一个TGT对象,放入自己的缓存(Session);同时,CAS生成cookie(叫TGC,个人理解,其实就是TGT的SessionId),写入浏览器。TGT对象的ID就是cookie的值,当HTTP再次请求到来时,如果传过来的有CAS生成的cookie,则CAS以此cookie值(SessionId)为key查询缓存中有无TGT(Session),如果有的话,则说明用户之前登录过,如果没有,则用户需要重新登录。

  • TGC (Ticket-granting cookie)
    上面提到,CAS-Server生成TGT放入自己的Session中,而TGC就是这个Session的唯一标识(SessionId),以Cookie形式放到浏览器端,是CAS Server用来明确用户身份的凭证。(如果你理解Session的存放原理的话就很好理解)

  • ST(ServiceTicket)
    ST是CAS为用户签发的访问某一服务票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,如果用户的请求中包含cookie,则CAS会以此cookie值为key查询缓存中有无TGT,如果存在TGT,则用此TGT签发一个ST,返回给用户。用户凭借ST去访问service,service拿ST去CAS验证,验证通过后,允许用户访问资源。

为了保证ST的安全性:ST 是基于随机生成的,没有规律性。而且,CAS规定 ST 只能存活一定的时间,然后 CAS Server 会让它失效。而且,CAS 协议规定ST只能使用一次,无论 Service Ticket 验证是否成功, CASServer 都会清除服务端缓存中的该 Ticket ,从而可以确保一个 Service Ticket 不被使用两次。

RememberMe 之 TGC

从分析咱们得知,TGC是CAS-Server生成以Cookie形式放到浏览器端的,那么RememberMe这个功能,肯定又与浏览器相关,则就与TGC有关呀。
下面咱们就看一下,用户login请求的响应头 set-cookie中存在TGC属性,但是在浏览器的cookies中并没有TGC的记录。
在这里插入图片描述

思考:是什么导致了TGC没有被写入cookie呢?

我们发现set-cookie中,存在两个属性 Secure 及 HttpOnly

  1. secure属性
    当设置为true时,表示创建的 Cookie 会被以安全的形式向服务器传输,也就是只能在 HTTPS 连接中被浏览器传递到服务器端进行会话验证,如果是 HTTP 连接则不会传递该信息,所以不会被窃取到Cookie 的具体内容。
    换句话说,如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的。

  2. HttpOnly属性
    如果在Cookie中设置了"HttpOnly"属性,那么通过程序(JS脚本、Applet等)将无法读取到Cookie信息,这样能有效的防止XSS攻击。

对于以上两个属性,
首先,secure属性是防止信息在传递的过程中被监听捕获后信息泄漏,HttpOnly属性的目的是防止程序获取cookie后进行攻击。
其次,GlassFish2.x支持的是servlet2.5,而servlet2.5不支持Session Cookie的"HttpOnly"属性。不过使用Filter做一定的处理可以简单的实现HttpOnly属性。GlashFish3.0(支持servlet3.0)默认开启Session Cookie的HttpOnly属性。
也就是说两个属性,并不能解决cookie在本机出现的信息泄漏的问题(FireFox的插件FireBug能直接看到cookie的相关信息)。

总结

问题原因

基于安全的考虑,CAS Server默认会给TGC的Cookie加上secure选项。而请求协议又是HTTP,最终导致了响应头Cookie中的TGC未被提交到服务端,导致CAS的Remember功能不生效。

解决

将CAS的 TGC secure改为false(会降低CAS的安全性):

application.properties:

cas.tgc.secure=false

哎,解决方案出了之后,终于松了一口气,代码还是棒棒的,都是配置惹的祸。

你可能感兴趣的:(CAS)