<!-- 该过滤器用于实现单点登出功能,可选配置。 --> <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>
那么这个是在什么时候会触发呢,这个是在你登陆的任意客户端,调用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); } } } } .... }