CAS-Client客户端研究--SingleSignOutFilter

<!-- 

该过滤器用于实现单点登出功能,可选配置。

 -->
<filter>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

SingleSignOutFilter ,主要是在有ticket参数的时候,将session放到sessionMappingStorage,如果参数中存在logoutRequest,则注销session,大家可能要问了,那什么时候去注销sessionMappingStorage的东西呢?这是靠SingleSignOutHttpSessionListener来实现的,当有session被销毁的时候,触发将sessionMappingStorage中对应sessionid中的数据删除。所以在配置单点登出的时候,一定要配置这个监听器,否则客户端很容易导致内存溢出的。让我们先来看看SingleSignOutFilter 的整体逻辑。

那么这个是在什么时候会触发呢,这个是在你登陆的任意客户端,调用https://xxx:8443/logout,这个取得cookie里面的TGT数据,找到TGT中关联的所有ST对应的地址,向每个地址方式一个http请求,并传递logoutRequest参数。

配置web.xml




我们来看看源代码是怎么实现的吧:

    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {  
          // 转换参数  
        final HttpServletRequest request = (HttpServletRequest) servletRequest;  
        //判断参数中是否具有artifactParameterName属性指定的参数名称,默认是ticket  
          if (handler.isTokenRequest(request)) {  
            // 如果存在,在本地sessionMappingStorage中记录session。  
              handler.recordSession(request);   
          } else if (handler.isLogoutRequest(request)) {//判断是否具有logoutParameterName参数指定的参数,默认参数名称为logoutRequest  
            // 如果存在,则在sessionMappingStorage中删除记录,并注销session。  
            handler.destroySession(request);  
              // 注销session后,立刻停止执行后面的过滤器  
              return;  
          } else {  
              log.trace("Ignoring URI " + request.getRequestURI());  
          }  
          //条件都不满足,继续执行下面的过滤器  
          filterChain.doFilter(servletRequest, servletResponse);  
      }  

public final class SingleSignOutHandler {
...
    /**
     * Determines whether the given request contains an authentication token.
     *
     * @param request HTTP reqest.
     *
     * @return True if request contains authentication token, false otherwise.
     */
    public boolean isTokenRequest(final HttpServletRequest request) {
        return CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.artifactParameterName));
    }

    /**
     * Determines whether the given request is a CAS logout request.
     *
     * @param request HTTP request.
     *
     * @return True if request is logout request, false otherwise.
     */
    public boolean isLogoutRequest(final HttpServletRequest request) {
        return "POST".equals(request.getMethod()) && !isMultipartRequest(request) &&
            CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName));
    }

    /**
     * Associates a token request with the current HTTP session by recording the mapping
     * in the the configured {@link SessionMappingStorage} container.
     * 
     * @param request HTTP request containing an authentication token.
     */
 public void recordSession(final HttpServletRequest request) {
        final HttpSession session = request.getSession(true);

        final String token = CommonUtils.safeGetParameter(request, this.artifactParameterName);
       
        try {
            this.sessionMappingStorage.removeBySessionById(session.getId());
        } catch (final Exception e) {
            // ignore if the session is already marked as invalid.  Nothing we can do!
        }
        sessionMappingStorage.addSessionById(token, session);
    }
   
    /**
     * Destroys the current HTTP session for the given CAS logout request.
     *
     * @param request HTTP request containing a CAS logout message.
     */
    public void destroySession(final HttpServletRequest request) {
        final String logoutMessage = CommonUtils.safeGetParameter(request, this.logoutParameterName);
               
        final String token = XmlUtils.getTextForElement(logoutMessage, "SessionIndex");
        if (CommonUtils.isNotBlank(token)) {
            final HttpSession session = this.sessionMappingStorage.removeSessionByMappingId(token);

            if (session != null) {
                String sessionID = session.getId();
               
                try {
                    session.invalidate();
                } catch (final IllegalStateException e) {
                    log.debug("Error invalidating session.", e);
                }
            }
        }
    }
....
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值