protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) { final boolean allowAnyProxy = getBoolean(ConfigurationKeys.ACCEPT_ANY_PROXY); final String allowedProxyChains = getString(ConfigurationKeys.ALLOWED_PROXY_CHAINS); final String casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX); final Class<? extends Cas20ServiceTicketValidator> ticketValidatorClass = getClass(ConfigurationKeys.TICKET_VALIDATOR_CLASS); final Cas20ServiceTicketValidator validator; //根据servlet拦截器的初始化参数来判断,如果是被代理端(被调用的应用) if (allowAnyProxy || CommonUtils.isNotBlank(allowedProxyChains)) { final Cas20ProxyTicketValidator v = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix, this.defaultProxyTicketValidatorClass); v.setAcceptAnyProxy(allowAnyProxy); v.setAllowedProxyChains(CommonUtils.createProxyList(allowedProxyChains)); validator = v; } else { //如果是代理端(类似nginx) validator = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix, this.defaultServiceTicketValidatorClass); } validator.setProxyCallbackUrl(getString(ConfigurationKeys.PROXY_CALLBACK_URL)); validator.setProxyGrantingTicketStorage(this.proxyGrantingTicketStorage);
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(), getSSLConfig()); validator.setURLConnectionFactory(factory);
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
if (!preFilter(servletRequest, servletResponse, filterChain)) { return; }
final HttpServletRequest request = (HttpServletRequest) servletRequest; final HttpServletResponse response = (HttpServletResponse) servletResponse; final String ticket = retrieveTicketFromRequest(request);
if (CommonUtils.isNotBlank(ticket)) { logger.debug("Attempting to validate ticket: {}", ticket);
try { //验证ticket的有效性 final Assertion assertion = this.ticketValidator.validate(ticket, constructServiceUrl(request, response));
上面提到我是使用redis来当做分布式session来使用,那么单点登出实现的逻辑是在gateway中提供统一的单点退出接口,用户调用此接口后清除redies中缓存的信息,并且重定向到CAS Service 调用/logout方法,并且在url中带上service参数后面跟上退出成功后cas重定向到的地址,这样在清除掉本地缓存的时又清楚了CAS Service中缓存的TGT信息实现单点退出.