IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Cas5+分布式session应用总结(二) -> 正文阅读

[Java知识库]Cas5+分布式session应用总结(二)

前言:上一篇文章,介绍了分布式session不同实现方式以及各自的优缺点,并且对redis+cookie的方式着重讲解。Cas5单点登录+分布式session应用总结_weixin_54983211的博客-CSDN博客

今天这篇文章分以下几部分。

目录

1.1? SSO基本概念以及应用场景。

1.2 cas相关基本概念、单点登录、登出流程。

1.3 cas+分布式session在企业中的具体项目分析。

? ? ? ? 1.3.1 web应用集成原生cas

? ? ? ? 1.3.2 springsecurity集成cas


1.1? SSO基本概念以及应用场景。

单点登录全称Single Sign On,简称SSO。一言以蔽之:一处登录,处处登录。一处登出,处处登出。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

最初,项目的所有功能都在一个应用中,用一个tomcat部署,称为单体应用。用户登录后,服务端利用用户请求携带的cookie即可识别用户信息。

? ? ? ? ? ? ? ? ? ??

?随着业务的发展,单体应用已经无法满足高并发的场景取而代之的是微服务、分布式、集群的架构。如上图所示:在门户中用户浏览某个摸块的新闻,这个板块后面可以是一个单独应用提供服务。每个应用都需要识别用户的身份执行登录流程,在门户站点用户每次点击不同的板块进去不同的应用都跳到登录页面,这显然是不合理的,而且登录代码在每个应用中维护复杂,不利于应用的扩展。

应对上面的问题,应运而生了一种技术,称为单点登录(sso)技术。通俗的讲就是将每个应用的登录功能抽取出来,形成一个SSO服务。这个服务只负责登录。而原来应用中只保留简单的session验证和授权的逻辑。

第一次用户访问门户被重定向到cas server登录页面,登录成功后cas server会返回一个登录成功的凭证ticket,当用户在门户站点访问其他应用的url上会携带ticket,请求到二级应用时,二级应用拿到ticket只需要向cas server验证这个ticket是否有效,如果有效,直接进入应用校验session即可完成登录。底层的逻辑对于用户来说是透明的。


1.2 cas相关基本概念、单点登录、登出流程。

? ?TGT(Ticket Grangting Ticket)

????????TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后,CAS生成cookie(叫TGC),写入浏览器,同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是cookie的值。当HTTP再次请求到来时,如果传过来的有CAS生成的cookie,则CAS以此cookie值为key查询缓存中有无TGT ,如果有的话,则说明用户之前登录过,如果没有,则用户需要重新登录。

? ?ST(Service Ticket)

????????ST是CAS为用户签发的访问某一service的票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,如果用户的请求中包含cookie,则CAS会以此cookie值为key查询缓存中有无TGT,如果存在TGT,则用此TGT签发一个ST,返回给用户。用户凭借ST去访问service,service拿ST去CAS验证,验证通过后,允许用户访问资源。

下面是官网给出的cas单点登录、登出详细流程。

单点登录认证流程

1)用户访问应用系统(cas-client),被拦截跳转到cas-server进行登录,输入正确的用户信息。

2)登录成功后,cas-server签发一个TGC票据,写入浏览器同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是cookie的值,并再次跳转到cas-client,同时携带着ST票据。

cas-client发现有ST票据则拿着ST票据去cas-server验证,如果验证通过,则返回用户名信息

3)cas-client登录成功,用户访问另一个cas-client2时,也会被拦截再次跳转到cas-server发现TGC票据生成的TGT对象的ID值存在则直接验证通过,签发一个ST票据给cas-client2。

单点登出流程:

1)用户页面执行登出操作,当前应用服务器会把这个登出请求重定向到CAS server。

2)CAS server接受登出请求后,会检测用户的TGC Cookie,把对应的session清除,同时会找到所有通过该TGC sso登录的应用服务器URL提交请求,所有的回调请求中,包含一个参数logoutRequest,访问这个登出URL。

3)所有收到logoutRequest请求的应用服务器(就是CAS client)会解析这个参数,取得sessionId,根据这个Id取得session后,把session删除。这样就实现单点登出的功能。

1.3 cas+分布式session在企业中的具体项目分析。

1.3.1 web应用集成原生cas

web应用通过web.xml集成原生cas

?在web.xml配置CAS相关过滤器,以及分布式session过滤器。

(分布式session过滤器在上篇文章讲到,这里不在赘述Cas5单点登录+分布式session应用总结_weixin_54983211的博客-CSDN博客

过滤器严格按照执行顺序来执行。

1)用户第一次请求系统,先进入RedisSessionFilter过滤器,生成session,存入redis并且设置cookie sessionId。

2)SingleSignOutFilter

请求到达第二个CAS Single Sign Out Filter 单点登录过滤器

原来CAS Single Sign Out Filter的类为SingleSignOutFilter,这里我重写了他的父类AbstractConfigurationFilter,实现了单点登出,销毁分布式session.

当请求进去第二个拦截器,SingleSignOutHandler的process(request,response)来处理请求

如果是tokenRequest,就会执行recordSession,通过request.getSession方法从redis获取session.并建立token(service-ticket)与session的关系,将token作为key,session为value保存到sessionMapppingStorage对象中,至于为什么这么做,在下面的destroySession方法中就会明白了。

?如果是logoutRequest就会执行destroySession方法(注意这里logoutRequest是由cas-server发过来的无法通过request.getSession()方法来获取应用原本的session进而销毁,所以在上面recordSession方法中根据token与session关联起来,保存到Map中),获取token,从map中获取session并且从redis中销毁分布式session,完成注销。

CAS Authentication Filter

当用户第一次请求页面,即不是tokenRequest也不是logoutRequest,第二个过滤不做处理直接执行filterChain.doFilter放行,这时进入到第三个过滤器CAS Authentication Filter。

public class AuthenticationFilter extends AbstractCasFilter {
    public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
            final FilterChain filterChain) {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        //从redis获取分布式session
        final HttpSession session = request.getSession(false);
        //从session获取assertion对象(下面的ticketValidation执行票据校验的时候assertion对象才有的)
        final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
        //如果票据校验成功assertion对象不等于null,成功进去系统首页
        if (assertion != null) {
            filterChain.doFilter(request, response);
            return;
        }
        //首次登录assertion为null
        //serviceUrl为应用url,执行登录后调回来的地址
        final String serviceUrl = constructServiceUrl(request, response);
        final String ticket = retrieveTicketFromRequest(request);
        //这时还没有去cas-server执行登录所有ticket=null
        if (CommonUtils.isNotBlank(ticket)) {
            filterChain.doFilter(request, response);
            return;
        }
        final String modifiedServiceUrl = serviceUrl;
        logger.debug("no ticket and no assertion found");
        // urlToRedirectTo cas server login url
        final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl,
                getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
        logger.debug("redirecting to \"{}\"", urlToRedirectTo);
        //跳转到cas执行登录
        this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);
    }
}

CAS Authentication Filter将未登录用户踢到cas登录页面,去执行登录。登录过的用户,从分布式session用获取assertion(票据校验成功assertion!=null),进入到系统首页。

Cas30ProxyReceivingTicketValidationFilter

当cas server执行完登录操作后,就会执行TicketValidationFilter。

如果没有特别的需求,使用原本的Cas30ProxyReceicingTicketValidation就可以了,我们项目需要在ticket验证成功执行特别的操作,所以重写了Cas30ProxyReceivingTicketValidationFilter类的onSuccessfulValidation方法。

public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
 public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
            final FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        //获取service-ticket,因为这里以及执行完cas登录流程是携带ticket的
        final String ticket = retrieveTicketFromRequest(request);
        if (CommonUtils.isNotBlank(ticket)) {
            logger.debug("Attempting to validate ticket: {}", ticket);
                // cas-client执行验证去cas-server验证票据,并返回assertion
                final Assertion assertion = this.ticketValidator.validate(ticket,
                        constructServiceUrl(request, response));
                request.setAttribute(CONST_CAS_ASSERTION, assertion);
                //如果启用session 把assertion对象放入session中
                if (this.useSession) {
                    request.getSession().setAttribute(CONST_CAS_ASSERTION, assertion);
                }
                //执行ticket校验成功方法回调
                onSuccessfulValidation(request, response, assertion);
                if (this.redirectAfterValidation) {
                    logger.debug("Redirecting after successful ticket validation.");
                    response.sendRedirect(constructServiceUrl(request, response));
                    return;
                }
        }
        filterChain.doFilter(request, response);
    }
}

去cas-server验证完ticket后,将assertion对象放入session中(票据校验失败的话,assertion=null),执行重定向跳转到应用首页。

?以上流程是cas client端执行登录的源代码流程。这里分析的时候需要注意,浏览器执行了两次重定向。一次是在登录的时候重定向到cas登录页面,执行登录成功后,cas-server重定向到应用中。所以在web.xml 配置的过滤器从上到下执行了两遍。第一遍和第二遍的参数是不一样的。

? 1.3.2 springsecurity集成cas

? ? ? ? 由于篇幅较长,springsecurity集成cas将在下一章讲解;

?

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 10:55:44  更:2021-12-10 10:56:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:08:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码