CAS-5.2.6单点登录-退出原理

article/2025/9/4 0:04:53

退出原理流程图:

cas的退出有三种模式:

 

  • NONE:不支持单点登录
  • BACK_CHANNEL:隐式退出(默认)
  • FRONT_CHANNEL:显式退出 

参数说明

参考官网地址 

 https://apereo.github.io/cas/5.2.x/installation/Configuration-Properties.html#logout 

#配置单点登出
#配置允许登出后跳转到指定页面
cas.logout.followServiceRedirects=false
#跳转到指定页面需要的参数名为 service
cas.logout.redirectParameter=service
#登出后需要跳转到的地址,如果配置该参数,service将无效。
cas.logout.redirectUrl=https://www.taobao.com
#在退出时是否需要 确认退出提示   true弹出确认提示框  false直接退出
cas.logout.confirmLogout=true
#是否移除子系统的票据
cas.logout.removeDescendantTickets=true
#禁用单点登出,默认是false不禁止
#cas.slo.disabled=true
#默认异步通知客户端,清除session
#cas.slo.asynchronous=true

 cas 默认登出后默认会跳转到CASServer的登出页,若想跳转到其它资源,可在/logout的URL后面加上service=jumpurl,例如:https://www.server.com:8443/cas/logout?service=https://www.baidu.com.com 但默认servcie跳转不会生效,需要在 cas服务端的application.properties添加cas.logout.followServiceRedirects=true .配置了cas.slo.disabled=true 将禁用单点登出。调用登出将无效.

 客户端退出模式必须配置:

/*** 登出过滤器* @return*/@Beanpublic FilterRegistrationBean filterSingleRegistration() {SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();singleSignOutFilter.setCasServerUrlPrefix(casConfig.getServerUrlPrefix());FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setName("singleSignOutFilter");filterRegistrationBean.setFilter(new DelegatingFilterProxy(singleSignOutFilter));filterRegistrationBean.setOrder(2);filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));return filterRegistrationBean;}
SingleSignOutFilter源码:
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,final FilterChain filterChain) throws IOException, ServletException {final HttpServletRequest request = (HttpServletRequest) servletRequest;final HttpServletResponse response = (HttpServletResponse) servletResponse;//判断 初始化if (!this.handlerInitialized.getAndSet(true)) {HANDLER.init();}//判断是正常请求还是退出请求if (HANDLER.process(request, response)) {filterChain.doFilter(servletRequest, servletResponse);}
}
public boolean process(final HttpServletRequest request, final HttpServletResponse response) {//正常请求if (isTokenRequest(request)) {logger.trace("Received a token request");recordSession(request);return true;} //退出请求if (isLogoutRequest(request)) {logger.trace("Received a logout request");//销毁sessiondestroySession(request);return false;} logger.trace("Ignoring URI for logout: {}", request.getRequestURI());return true;
}private void recordSession(final HttpServletRequest request) {final HttpSession session = request.getSession(this.eagerlyCreateSessions);if (session == null) {logger.debug("No session currently exists (and none created).  Cannot record session information for single sign out.");return;}final String token = CommonUtils.safeGetParameter(request, this.artifactParameterName, this.safeParameters);logger.debug("Recording session for token {}", token);try {this.sessionMappingStorage.removeBySessionById(session.getId());} catch (final Exception e) {// ignore if the session is already marked as invalid. Nothing we can do!}//保存sessionsessionMappingStorage.addSessionById(token, session);
}
private boolean isLogoutRequest(final HttpServletRequest request) {if ("POST".equalsIgnoreCase(request.getMethod())) {return !isMultipartRequest(request)&& CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName,this.safeParameters));}if ("GET".equalsIgnoreCase(request.getMethod())) {return CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters));}return false;}
private void destroySession(final HttpServletRequest request) {//在服务端设置完后跳转到客户端互获取String logoutMessage = CommonUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters);//获取退出信息if (CommonUtils.isBlank(logoutMessage)) {logger.error("Could not locate logout message of the request from {}", this.logoutParameterName);return;}if (!logoutMessage.contains("SessionIndex")) {logoutMessage = uncompressLogoutMessage(logoutMessage);}logger.trace("Logout request:\n{}", logoutMessage);final String token = XmlUtils.getTextForElement(logoutMessage, "SessionIndex");if (CommonUtils.isNotBlank(token)) {//删除session中的信息final HttpSession session = this.sessionMappingStorage.removeSessionByMappingId(token);if (session != null) {final String sessionID = session.getId();logger.debug("Invalidating session [{}] for token [{}]", sessionID, token);try {//销毁sessionsession.invalidate();} catch (final IllegalStateException e) {logger.debug("Error invalidating session.", e);}this.logoutStrategy.logout(request);}}
}

服务端退出源码:

     DefaultSingleLogoutServiceMessageHandler类,他是负责发送退出请求到我们客户端的,实现了SingleLogoutServiceMessageHandler 这个接口,找到这接口的时候,发现里面就一个方法

LogoutRequest handle(WebApplicationService singleLogoutService, String ticketId);

 @Override
public LogoutRequest handle(final WebApplicationService singleLogoutService, final String ticketId) {
//判断是否已经登出if (singleLogoutService.isLoggedOutAlready()) {LOGGER.debug("Service [{}] is already logged out.", singleLogoutService);return null;}
//处理服务注销请求final WebApplicationService selectedService = WebApplicationService.class.cast(this.authenticationRequestServiceSelectionStrategies.resolveService(singleLogoutService));LOGGER.debug("Processing logout request for service [{}]...", selectedService);//取出这个注册的service服务的信息final RegisteredService registeredService = this.servicesManager.findServiceBy(selectedService);
//判断是否支持退出if (!serviceSupportsSingleLogout(registeredService)) {LOGGER.debug("Service [{}] does not support single logout.", selectedService);return null;}LOGGER.debug("Service [{}] supports single logout and is found in the registry as [{}]. Proceeding...", selectedService, registeredService);//获取logout的url,这个是我们自己注册进去的final URL logoutUrl = this.singleLogoutServiceLogoutUrlBuilder.determineLogoutUrl(registeredService, selectedService);LOGGER.debug("Prepared logout url [{}] for service [{}]", logoutUrl, selectedService);if (logoutUrl == null) {LOGGER.debug("Service [{}] does not support logout operations given no logout url could be determined.", selectedService);return null;}LOGGER.debug("Creating logout request for [{}] and ticket id [{}]", selectedService, ticketId);//封装退出的消息内容,将退出请求以及st封装起来final DefaultLogoutRequest logoutRequest = new DefaultLogoutRequest(ticketId, selectedService, logoutUrl);LOGGER.debug("Logout request [{}] created for [{}] and ticket id [{}]", logoutRequest, selectedService, ticketId);//判断是哪种模式下的退出请求,cas服务器分为三种final RegisteredService.LogoutType type = registeredService.getLogoutType() == null? RegisteredService.LogoutType.BACK_CHANNEL : registeredService.getLogoutType();LOGGER.debug("Logout type registered for [{}] is [{}]", selectedService, type);switch (type) {case BACK_CHANNEL://发送通知if (performBackChannelLogout(logoutRequest)) {logoutRequest.setStatus(LogoutRequestStatus.SUCCESS);} else {logoutRequest.setStatus(LogoutRequestStatus.FAILURE);LOGGER.warn("Logout message is not sent to [{}]; Continuing processing...", singleLogoutService.getId());}break;default:LOGGER.debug("Logout operation is not yet attempted for [{}] given logout type is set to [{}]", selectedService, type);logoutRequest.setStatus(LogoutRequestStatus.NOT_ATTEMPTED);break;}return logoutRequest;}
public boolean performBackChannelLogout(final LogoutRequest request) {try {LOGGER.debug("Creating back-channel logout request based on [{}]", request);final String logoutRequest = this.logoutMessageBuilder.create(request);final WebApplicationService logoutService = request.getService();//将发送退出后的设置为已发送logoutService.setLoggedOutAlready(true);LOGGER.debug("Preparing logout request for [{}] to [{}]", logoutService.getId(), request.getLogoutUrl());//封装消息final LogoutHttpMessage msg = new LogoutHttpMessage(request.getLogoutUrl(), logoutRequest, this.asynchronous);LOGGER.debug("Prepared logout message to send is [{}]. Sending...", msg);发送消息return this.httpClient.sendMessageToEndPoint(msg);} catch (final Exception e) {LOGGER.error(e.getMessage(), e);}return false;}

关于单点登出原理,参考博客:

https://blog.csdn.net/qq_34021712/article/details/81515317


http://chatgpt.dhexx.cn/article/KxcUbgy3.shtml

相关文章

CAS实现单点登录原理与实例解析

上几篇博客介绍了使用cookie实现同域和跨域系统的单点登录,本文将介绍通过CAS实现单点登录实例。 CAS是由耶鲁大学研发的单点登录服务器,主要分为服务端和客户端两个系统模块;本文将通过官网提供的实例进行介绍。 一、CAS实现SSO的原理与认…

简述CAS单点登录的实现原理

CAS(Central Authentication Service)单点登录系统是一种常见的身份验证和授权解决方案,它可以让用户在一个认证中心(CAS服务器)上登录,然后使用此登录信息访问多个应用程序而无需再次登录。 先了解几个名…

CAS单点登录原理解析及相关配置

1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter)中校验用户权限,如果没有权限则从Cookie中取出用户名密码进行登录,让用…

CAS 单点登录的实现原理(一)

一,会话和Cookie HTTP是无状态协议,客户端与服务端之间的每次通信都是独立的,而会话机制可以让服务端鉴别每次通讯过程中的客户端是否是同一个,从而保证业务的关联性。 Session是服务器使用一种类似于散列表的结构,用…

CAS单点登录原理及实现

CAS单点登录原理及实现 标签(空格分隔): 单点登录 CAS SSO ###目录 概念介绍搭建流程原理分析 ###概念介绍 CAS介绍 Central Authentication Service(缩写CAS)是一种针对万维网的单点登录协议。它的目的是允许一个用…

单点登录CAS实现

单点登录(Single Sign-On,简称SSO)是一种身份验证技术,它允许用户使用一组凭据(如用户名和密码)登录到多个应用程序或系统中,而无需在每个应用程序或系统中单独登录。这种技术可以提高用户体验&…

CAS单点登录原理及改造

CAS是由耶鲁大学开发的单点登录系统,其核心的知识点包括以下几个概念: 1) TGT: 票据,或称大令牌,在登录成功之后生成,其中包含了用户信息 2) TGC: TGT的key,TGT存储在session中,TGC以cookie形式保存在浏览器…

SSO单点登录原理详解(从入门到精通)

本文主要对SSO单点登录与CAS、OAuth2.0两种授权协议的关系和原理进行详细说明。 1. 基础概念 SSO单点登录(Single sign-on) 所谓单点登录就是在多个应用系统中,用户只需登录一次就可以访问所有相互信任的系统。 CAS 中央认证服务&#xf…

CAS单点登录的实现

这篇文章对CAS单点登录具体实现的一些步骤就行讲述,至于CAS单点登录的实现原理分析,请参看下面这篇文章:CAS单点登录原理分析(一) https://blog.csdn.net/qq_41258204/article/details/84036875 CAS 包含两个部分: CAS Server 和…

CAS单点登录原理解析

推荐阅读 1. SpringBoot 整合篇 2. 手写一套迷你版HTTP服务器 3. 记住:永远不要在MySQL中使用UTF-8 4. Springboot启动原理解析 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访…

CAS单点登录的实现(二)

这篇文章对CAS单点登录具体实现的一些步骤就行讲述,至于CAS单点登录的实现原理分析,请参看下面这篇文章: CAS单点登录原理分析(一) https://blog.csdn.net/qq_41258204/article/details/84036875 CAS 包含两个部分: CAS Server 和…

CAS单点登录系列之原理简单介绍

文章目录 一、 SSO简介1.1 单点登录定义1.2 单点登录角色1.3 单点登录分类 二、 CAS简介2.1 CAS简单定义2.2 CAS体系结构2.3 CAS原理 三、CAS服务端部署附录 一、 SSO简介 1.1 单点登录定义 单点登录(Single sign on),英文名称缩写SSO,SSO的意思就是在…

CAS实现单点登录SSO执行原理探究(终于明白了)

一、不落俗套的开始 1、背景介绍 单点登录:Single Sign On,简称SSO,SSO使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 CAS框架:CAS(Central Authentication Service)是实现SSO单点登录的框架。 2、盗一张学习CAS绝大多都看过的图以及执…

CAS实现单点登录

1.简介 SSO单点登录 在多个相互信任的系统中,用户只需要登录一次就可以访问其他受信任的系统。 新浪微博与新浪博客是相互信任的应用系统。 *当用户首次访问新浪微博时,新浪微博识别到用户未登录,将请求重定向到认证中心,认证中心…

cas server + cas client 单点登录 原理介绍

CAS 介绍 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点: 开源的企业级单点登录解决方案。 CAS Server 为需要独立部署的 Web 应用…

CAS单点登录原理(包含详细流程,讲得很透彻,耐心看下去一定能看明白!)

转载地址 http://www.cnblogs.com/lihuidu/p/6495247.html 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter)中校验用户权限,如果没有…

CAS方式实现单点登录

单点登录,英文是 Single Sign On,缩写为 SSO。 多个站点(192.168.1.20X)共用一台认证授权服务器(192.168.1.110,用户数据库和认证授权模块共用)。用户经由其中任何一个站点(比如 192.168.1.201)登录后,可以免登录访问其他所有站点…

单点登录之CAS原理和实现

1.开源单点登录系统CAS入门 1.1 什么是单点登录 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用…

CAS单点登录原理分析(一)

一,业务分析 在分布式系统架构中,假设把上述的三个子系统部署在三个不同的服务器上。前提是用户登录之后才能访问这些子系统。那么使用传统方式,可能会存在这样的问题: 1.当访问用户中心,需要用户登录帐号 2.当访问购物…

cas单点登录原理与实现(整合springsecurity)

一、cas原理分析 SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。CAS是一种基于http协议的B/S应用系统单点登录实现方案,认识CAS之前首先要熟悉http协议、Session与Cookie…