解决jasig CAS server端 ticketGrantingTicket超时后的一个bug

最近研究cas,发现在设置ticketGrantingTicket超时后,打开https://tski.com:8443/cas 仍然显示成功


ticketExpirationPolicies.xml

<!-- This argument is the time a ticket can exist before its considered expired. 设置为5秒超时-->
<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">

<constructor-arg
index="0"
value="5000" />
</bean>


ticketRegistry.xml

<!-- 10秒检查一次是否有ticket需要clean -->
<bean id="triggerJobDetailTicketRegistryCleaner" class="org.springframework.scheduling.quartz.SimpleTriggerBean"
p:jobDetail-ref="jobDetailTicketRegistryCleaner"
p:startDelay="2000"
p:repeatInterval="10000" />


仍然显示成功
[img]http://dl.iteye.com/upload/attachment/587461/3bab4db5-aff0-3e9f-af56-5082d88b86b5.png[/img]


所以猜测,TGT超时与使用https://tski.com:8443/cas/logout 不同地方在于,后者清除了cookie中的TGT

于是找到logout的处理代码
org.jasig.cas.web.LogoutController

protected ModelAndView handleRequestInternal(
final HttpServletRequest request, final HttpServletResponse response)
throws Exception {
final String ticketGrantingTicketId = this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request);
final String service = request.getParameter("service");

if (ticketGrantingTicketId != null) {
this.centralAuthenticationService
.destroyTicketGrantingTicket(ticketGrantingTicketId);
//清除cookie
this.ticketGrantingTicketCookieGenerator.removeCookie(response);
this.warnCookieGenerator.removeCookie(response);
}

if (this.followServiceRedirects && service != null) {
return new ModelAndView(new RedirectView(service));
}

return new ModelAndView(this.logoutView);
}


而TGT超时时,cas server 不能获取cookie

继续猜测,打开https://tski.com:8443/cas时,cas server只判断了cookie中是否有TGT,但是没判断org.jasig.cas.ticket.registry.TicketRegistry中是否还存在TGT。

找到login-webflow.xml
    

<!-- 在flowScope.ticketGrantingTicketId && flowScope.service 为null的情况下,页面会跳转到viewGenericLoginSuccess -->
<on-start>
<evaluate expression="initialFlowSetupAction" />
</on-start>

<decision-state id="ticketGrantingTicketExistsCheck">
<if test="flowScope.ticketGrantingTicketId neq null" then="hasServiceCheck" else="gatewayRequestCheck" />
</decision-state>

...
<decision-state id="hasServiceCheck">
<if test="flowScope.service != null" then="renewRequestCheck" else="viewGenericLoginSuccess" />
</decision-state>


所以现在要确认flowScope.ticketGrantingTicketId , flowScope.service 是什么东西
找到org.jasig.cas.web.flow.InitialFlowSetupAction

protected Event doExecute(final RequestContext context) throws Exception {
final HttpServletRequest request = WebUtils.getHttpServletRequest(context);
if (!this.pathPopulated) {
... }

//ticketGrantingTicketId是从cookie里取的,问题很清楚了
context.getFlowScope().put(
"ticketGrantingTicketId", this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request));
context.getFlowScope().put(
"warnCookieValue",
Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request)));
//service 只有在从其他系统跳转到cas server时才可能不是null
final Service service = WebUtils.getService(this.argumentExtractors,
context);

if (service != null && logger.isDebugEnabled()) {
logger.debug("Placing service in FlowScope: " + service.getId());
}

context.getFlowScope().put("service", service);

return result("success");
}


最后,修改代码
org.jasig.cas.web.flow.InitialFlowSetupAction

//注入 ticketRegistry
@NotNull
private TicketRegistry ticketRegistry;

public TicketRegistry getTicketRegistry() {
return ticketRegistry;
}

public void setTicketRegistry(TicketRegistry ticketRegistry) {
this.ticketRegistry = ticketRegistry;
}


protected Event doExecute(final RequestContext context) throws Exception {
final HttpServletRequest request = WebUtils.getHttpServletRequest(context);
if (!this.pathPopulated) {
... }
//从ticketRegistry中获取TGT
context.getFlowScope().put(
"ticketGrantingTicketId", ticketRegistry.getTicket(this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request)));
context.getFlowScope().put(
"warnCookieValue",
Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request)));

final Service service = WebUtils.getService(this.argumentExtractors,
context);

if (service != null && logger.isDebugEnabled()) {
logger.debug("Placing service in FlowScope: " + service.getId());
}

context.getFlowScope().put("service", service);

return result("success");
}


修改cas-servlet.xml
<!-- 最后一行 p:ticketRegistry-ref="ticketRegistry"  ,注入ticketRegistry -->
<bean id="initialFlowSetupAction" class="org.jasig.cas.web.flow.InitialFlowSetupAction"
p:argumentExtractors-ref="argumentExtractors"
p:warnCookieGenerator-ref="warnCookieGenerator"
p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator"
p:ticketRegistry-ref="ticketRegistry"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CAS服务中,可以在`cas.properties`配置文件中设置`cas.login.redirectParameter`参数,该参数指定了登录成功后重定向到客户应用程序时所需的参数名,默认值为`service`。如果您想要将用户重定向到客户应用程序的特定路径,可以在客户应用程序的URL中添加`service`参数,例如: ``` https://example.com/myapp?service=https://example.com/myapp/home ``` 当用户成功登录CAS后,CAS将重定向到以下URL: ``` https://example.com/myapp/home?ticket=ST-12345-abcde... ``` 其中,`ticket`参数是CAS服务生成的票据,客户应用程序可以使用该票据向CAS服务验证用户的身份信息。在客户应用程序中,可以使用CAS客户库来验证票据,并将用户重定向到特定的路径。例如,在Java应用程序中,可以使用`org.jasig.cas.client.validation.Cas20ServiceTicketValidator`类来验证票据,示例代码如下: ```java String serviceUrl = "https://example.com/myapp/home"; String ticket = request.getParameter("ticket"); Cas20ServiceTicketValidator validator = new Cas20ServiceTicketValidator("https://cas.example.com"); Assertion assertion = validator.validate(ticket, serviceUrl); if (assertion != null) { // 用户身份验证成功,将用户重定向到特定的路径 response.sendRedirect("https://example.com/myapp/home"); } else { // 用户身份验证失败,处理错误信息 // ... } ``` 在上述示例代码中,`serviceUrl`参数指定了客户应用程序的特定路径,`ticket`参数是CAS服务生成的票据,`Cas20ServiceTicketValidator`类用于验证票据,如果验证成功,则将用户重定向到特定的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值