`

关于CAS单点登录超时处理总结

阅读更多

1 错误场景                                   

     cas session 超时问题:XMLHttpRequest cannot loadhttps://www.hf.com:8443/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2Fvms%2Fcheck%2FfindPendingCheck%2F. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

    部署问题:用nginx封装,service携带不过来。

 2 cas 针对session超时设置                       

    cas对于session超时设置,可以设置文件cas\WEB-INF\spring-configuration\ticketExpirationPolicies.xml 进行设置,如下所示:

  1. <bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy">  
  2.        <property name="sessionExpirationPolicy">  
  3.            <bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">  
  4.             <constructor-arg index="0" value="20000" />  
  5.                     </bean>  
  6.        </property>  
  1. <bean id="serviceTicketExpirationPolicy" class="org.jasig.cas.ticket.support.MultiTimeUseOrTimeoutExpirationPolicy">  
  2.     <!-- This argument is the number of times that a ticket can be used before its considered expired. -->  
  3.     <constructor-arg  
  4.         index="0"  
  5.         value="1" />  
  6.       
  7.     <!-- This argument is the time a ticket can exist before its considered expired.  -->  
  8.     <constructor-arg  
  9.         index="1"  
  10.         value="20000" />  
  11. </bean>  


    上述两个bean中,设置为20000毫秒(设置超时单位为毫秒),上述另个bean的机制就如同session机制一样,当用户没有与服务器的交互超过20秒,点击url,便会自动转到登录界面。单只是设置这一点是不够的,会有问题的。

    问题:当你的项目中也有对session的设置,以及对session时间的设置的时候,只设置cas的session超时是不管事的。

 3 配置完毕,对于ajax请求出现的错误        

    问 题的解决:所以我们需要把项目中session超时的时间和cas session超时的时间设置为一致,因为cas对session超时的处理,是在cas-client-core-3.2.1.jar 包中,而cas的客户端是和项目放在一起的,所以对session处理机制是一样的。

 

    当然上述的处理一般情况下是没有问题的,但当遇到ajax请求,就不可以了,会报如下错误:

XMLHttpRequest cannot load https://www.hf.com:8443/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2Fvms%2Fcheck%2FfindPendingCheck%2F. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

    千 万别被Origin蒙蔽,开始定位错误定位在跨域问题,因为网上查找说也是跨域问题,而实际上对于非ajax请求,cas拦截处理后是可以跳转到登录页面 的,这说明了是可以请求给cas的,只不过cas对ajax的请求无法做出session失效的处理,这怎么办呢?只能去改CAS源码了。不知道是cas 矮,还是自己太矮了。。。

 4 修改CAS源码,解决上述问题   

    经过查看错误日志,找到cas打印日志的地方,找到cas处理session的方法,修改的是/CAS_Client/src/org/jasig/cas/client/authentication/AuthenticationFilter.java这个java类。修改的doFilter方法如下所示。

  1. public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {  
  2.       final HttpServletRequest request = (HttpServletRequest) servletRequest;  
  3.       final HttpServletResponse response = (HttpServletResponse) servletResponse;  
  4.       final HttpSession session = request.getSession(false);  
  5.       final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;  
  6.   
  7.       if (assertion != null) {  
  8.           filterChain.doFilter(request, response);  
  9.           return;  
  10.       }  
  11.   
  12.       final String serviceUrl = constructServiceUrl(request, response);  
  13.       final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());  
  14.       final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);  
  15.   
  16.       if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {  
  17.           filterChain.doFilter(request, response);  
  18.           return;  
  19.       }  
  20.   
  21.       final String modifiedServiceUrl;  
  22.   
  23.       log.debug("no ticket and no assertion found");  
  24.       if (this.gateway) {  
  25.           log.debug("setting gateway attribute in session");  
  26.           modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);  
  27.       } else {  
  28.           modifiedServiceUrl = serviceUrl;  
  29.       }  
  30.       if (log.isDebugEnabled()) {  
  31.           log.debug("Constructed service url: " + modifiedServiceUrl);  
  32.       }  
  33.         
  34.       final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);  
  35.   
  36.       if (log.isDebugEnabled()) {  
  37.           log.debug("redirecting to \"" + urlToRedirectTo + "\"");  
  38.       }  
  39.         
  40.       log.debug("判断拼接的过程,参数, 最终拼接好的地址为: \"" + urlToRedirectTo + "\"");  
  41.         
  42.       //response.sendRedirect(urlToRedirectTo);  
  43.       String url = request.getRequestURL().toString();  
  44.       log.debug("url------request.getRequestURL().toString()=---------:" + url);  
  45.       String contextPath = request.getContextPath();  
  46.       log.debug("contextPath ---------request.getContextPath()=-------:" + contextPath);  
  47.         
  48.       url = url.substring(0, (url.indexOf(contextPath)+contextPath.length()));  
  49.       log.debug("url = ------session消失,截取到项目的url---" + url);  
  50.       String urls = urlToRedirectTo;  
  51.         
  52.       //判断是否是第一次转到.  
  53.       if("".equals(url)||url==null||url.length()==0){  
  54.           
  55.         log.debug("url--第一次为空,不截取-----" + url);  
  56.         urls = urlToRedirectTo;  
  57.         //response.sendRedirect(urlToRedirectTo);  
  58.       }else{  
  59.         urls = urls.substring(0, (urls.indexOf("service=")+8)) + URLEncoder.encode(url,"UTF-8");  
  60.       }  
  61.         
  62.       log.debug("urls --最终输入到浏览器的地址是-----------" + urls);  
  63.         
  64. response.setContentType("text/html;charset=UTF-8");  
  65. response.getWriter().write("<script languge='javascript'>window.location.href='"+urls+"/'</script>");  
  66.   }  


 

    这样不但解决了cas对ajax地址处理,并且解决了另一个问题,因为最初的改动不是上述的代码,中间出现了一个小插曲,部署的时候出现的bug,登录时service参数携带不过来。当我们把项目部署到linux上时,用nginx代理,并配置tomcat的sever.xml文件封装项目名称, 则样,域名“封装”了ip+端口号+项目名称,用户不需要再输入项目名称了。所以代码中对用户第一次登录做判断,判断是否是第一次登录还是session失效调用的这个方法,这样就解决了nginx代理出现的问题了。

 5  总结                                         

1)TGT时间:

 

在ticketExpirationPolicies.xml中,

 

 

 

<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">

 

 <!-- This argument is the time a ticket can exist before its considered expired.  -->

 

 <constructor-arg

 

  index="0"

 

  value="7200000" />

 

</bean>

 

这里进行设置的时间是TGT(ticket granting ticket)的时间,如果TGT时间到期,则需要进行重新登录。这里时间单位是毫秒,默认是两小时。

 

如果进行了rememberMe配置,则是在

 

<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy">

 

   

 

   <!-- 一般情况下的 cas session 实效时间 -->

 

   <property name="sessionExpirationPolicy">

 

    <bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">

 

           <constructor-arg index="0" value="60000" />

 

    </bean>

 

   </property>

 

   <!-- 全天免登录 情况下 cas session的实效时间 -->

 

   <property name="rememberMeExpirationPolicy">

 

    <bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">

 

           <constructor-arg index="0" value="1209600000" />

 

    </bean>

 

   </property>

 

</bean>

 

中的sessionExpirationPolicy进行配置。

 

 

 

2)rememberMe时间(记住登录状态时间)

 

在上面的rememberMeExpirationPolicy中进行配置。时间单位是毫秒。然后在ticketGrantingTicketCookieGenerator.xml中的

 

<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"

 

  p:cookieSecure="false"

 

  p:cookieMaxAge="-1"

 

  p:cookieName="CASTGC"

 

  p:cookiePath="/cas" 

 

  p:rememberMeMaxAge="1209600"/>

 

p:rememberMeMaxAge进行配置,两者时间保持一致,注意这里的时间单位是秒。
分享到:
评论

相关推荐

    菜鸟配置CAS单点登录

    手把手教你如何配置如下几项: 单点登录认证配置 配置为自定义数据库认证方式 获取登录用户名 单点退出 网站间建立信任关系 修改默认页面 超时设置 另附CAS实用网址

    spring security 参考手册中文版

    使用protect-pointcut添加安全性切入点 66 6.5默认AccessDecisionManager 67 6.5.1自定义AccessDecisionManager 67 6.6验证管理器和命名空间 67 7.示例应用程序 69 7.1教程示例 69 7.2联系人 69 7.3 LDAP样本 71 7.4...

    阿里云javasdk源码-java-ssm-qingcheng:java-ssm-qingcheng

    阿里云java ...rest高级api)、消息中间件(RabbitMQ发送与接受消息)、阿里云通信、开源单点登陆系统CAS、分布式事务、微信扫码支付(微信支付二维码、支付回调逻辑处理、推送支付通知、超时未支付订单处理)、...

    java开源包1

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包11

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包2

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包3

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包6

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包5

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包10

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包4

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包8

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包7

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包9

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包101

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    Java资源包01

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段04讲、多线程的休息室WaitSet详细介绍与知识点总结.mp4 │ 高并发编程第二阶段05讲、一个解释volatile关键字作用最好的例子.mp4 │ 高并发编程第二阶段06讲、Java内存模型以及CPU缓存不一致...

Global site tag (gtag.js) - Google Analytics