这个问题之前就发现过,最近有几个哥们一直在问我这个怎么搞,我手上在做另一个项目,cas就暂时搁浅了几周。现在我们来一起改一下你的应用(client2/3)的web.xml来解决这个2b问题,首先看下错误描述:
问题: 我登录了client2,又登录了client3,现在我把client2退出了,在client3里面我F5刷新了一下,结果页面报错:
未能够识别出目标 'ST-41-2VcnVMguCDWJX5zHaaaD-cas01.example.org'票根
- <span style="font-family:Microsoft YaHei;font-size:12px;">type Exception report
-
- message org.jasig.cas.client.validation.TicketValidationException:
-
- description The server encountered an internal error that prevented it from fulfilling this request.
-
- exception
-
- javax.servlet.ServletException: org.jasig.cas.client.validation.TicketValidationException:
- 鏈兘澶熻瘑鍒嚭鐩爣 'ST-41-2VcnVMguCDWJX5zHaaaD-cas01.example.org'绁ㄦ牴
-
- org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:155)
- org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:99)
- org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
- org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
- root cause
-
- org.jasig.cas.client.validation.TicketValidationException:
- 鏈兘澶熻瘑鍒嚭鐩爣 'ST-41-2VcnVMguCDWJX5zHaaaD-cas01.example.org'绁ㄦ牴
-
- org.jasig.cas.client.validation.Cas20ServiceTicketValidator.parseResponseFromServer(Cas20ServiceTicketValidator.java:73)
- org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:188)
- org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:132)
- org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:99)
- org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
- org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
- note The full stack trace of the root cause is available in the Apache Tomcat/7.0.37 logs.</span>
猜都能猜出来,我注销了,ticket已经失效了,现在我又发回到server端,它就报错了。(客户端发过去就报错了),以下就是cas ticket失效处理的一个很简单的解决办法,复杂的话,需要修改client源码进行异常处理。
1.所以针对这个情况,我只能在web.xml中下手了,(你也可以修改客户端的jar包中的一些java类,自己去做这个异常处理,接收所有在cas使用过程中会出错的处理,全部跳转到错误页面中,让掉线的人重新登录。在这里,我们采用web.xml配置一下)
2.这是官网解释:https://wiki.jasig.org/display/CASC/Configuring+the+Jasig+CAS+Client+for+Java+in+the+web.xml 它的解释:
The correct order of the filters in web.xml is necessary:
- AuthenticationFilter
- TicketValidationFilter (whichever one is chosen)
- HttpServletRequestWrapperFilter
- AssertionThreadLocalFilter
意思是说,过滤器链不要错,我之前的那篇教程里cas客户端配置web.xml没有使用这几个过滤器,现在我们重新使用它。
3.这是一个哥们之前解释的:我贴出来。
单点登出,客户端配置。我尝试使用SAML作为认证和Ticket校验,但是调试时发现单点登出取标识的方式只能识别CAS的认证和校验。
认证:org.jasig.cas.client.authentication.AuthenticationFilter
校验:org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
过滤器顺序:
1. CAS Single Sign Out Filter
2. CAS Validation Filter
3. CAS Authentication Filter
4. CAS HttpServletRequest Wrapper Filter
5. CAS Assertion Thread Local Filter
特别注意Validation在Authentication之前,因为我使用的是Cas20ProxyReceivingTicketValidationFilter。根据CAS文档描述:If you are using proxy validation, you should map the validation filter before the authentication filter.
4.ok,放上我的web.xml文件,废掉之前的cas验证过滤器(CAS Filter)。使用另一个过滤器(CAS Authentication Filter),并且增加另外三个过滤器(CAS Validation Filter,CAS HttpServletRequest Wrapper Filter,CAS Assertion Thread Local Filter),注意过滤器的顺序.
5.如果这样做了,你还需要一件事情,就是前台获取用户信息的方式改了,我的index.jsp改成了这个:
- <span style="font-family:Microsoft YaHei;font-size:12px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <%@page import="edu.yale.its.tp.cas.client.filter.CASFilter"%>
- <%@page import="org.jasig.cas.client.util.AssertionThreadLocalFilter"%>
- <%@page import="org.jasig.cas.client.util.HttpServletRequestWrapperFilter"%>
- <%@page import="org.jasig.cas.client.authentication.AttributePrincipal"%>
- <%@page import="org.jasig.cas.client.util.AbstractCasFilter"%>
- <%@page import="org.jasig.cas.client.validation.Assertion"%>
-
-
- <body>
-
- <h1>
- 登录成功,这是客户端2
- </h1>
- <br />
-
- 欢迎您:
-
- <%
-
-
- String username = "";
- AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
- if(principal != null){
- username = principal.getName();
- }
-
-
-
- %>
- 用户名:<%=username%></span>
ok,我的应用之间如果一个退出,另一个就算带ticket参数也不不再报错了,就算是测试组的兄弟拿到那段ticket复制粘贴到另一个浏览器中进行访问,也不会报错。
ps:
也有兄弟说可以通过修改C:\tomcat7\webapps\casServer\WEB-INF\spring-configuration\ticketExpirationPolicies.xml这个文件中的
-
- <util:constant id="SECONDS" static-field="java.util.concurrent.TimeUnit.SECONDS"/>
- <bean id="serviceTicketExpirationPolicy" class="org.jasig.cas.ticket.support.MultiTimeUseOrTimeoutExpirationPolicy"
- c:numberOfUses="1" c:timeToKill="${st.timeToKillInSeconds:10}" c:timeUnit-ref="SECONDS"/>
其中那个
c:numberOfUses="1" //使用ticket多少次
c:timeToKill="${st.timeToKillInSeconds:10}" //多少秒过期,默认10秒,你把这个改成10分钟玩玩。
这个方法我没有尝试,所以希望想尝试想折腾和想玩的兄弟狠狠的点击这个链接:http://bbs.csdn.net/topics/390111112