CAS前后端分离解决方案

  1. 关于CSS服务器的搭建和整合SpringBoot参考CAS5.3服务器搭建与客户端整合SpringBoot以及踩坑笔记

  2. 环境与需求

    • 后端:springboot

    • 前端: vue + element UI

    在登录后之后登录状态在系统中自主控制。

  3. 问题

    当接口在CAS过滤器中时候,CAS Client会检测是否登录(检测内容下面写),若没有登录会像前端发送请求重定向的请求。当前端和后端在不同电脑时候,前端不能够自动跳转。

    注:未深究其中缘由,在同台电脑,上面element ui + spring boot就可以直接完成到cas服务器登录页面的跳转。应该是跨域或者其他未知的原因

  4. 粗略的解决方法

    如果最后项目是部署在同一台服务上面的,可以在其他都完成的情况下,最后再放到同一台电脑上面进行开发。

  5. 简单看cas表层原理。

    1. 在自己浏览器中打开接口,后端拦截,指引页面重定向到cas服务器的登录页(接口在自己电脑运行就行),以上操作等同于地址栏直接输入:

      http://localhost:8332/cas/login?service=http://localhost:8888/接口名

      cas client拦截下来就是在验证未通过后,拼凑了一下service里面的内容。

    2. 在登录成功后,本地cookie会存入一条JSESSIONID为键,值为B5ABB0EB00A770036F284D65453B2593的记录。

    3. 在之后每次访问接口时候会在头中带上。

    4. CAS客户端是在每次登录成功后都会从请求头中拿到JSESSIONID去找服务器验证。成功的话就会把数据返回来。如果未成功(可能过期或者空)且当前接口在CAS过滤器authentication-url-patterns中配置了,就会重定向到CAS登录页。

    5. 所以,我们Cookie做键,值内容一起复制到postman中,在header中添加,同样得到了登录的效果。

    6. 以上得出:

      1. 不通过CAS Client的重定向,我们直接写url也可以获取登录成功的JSESSIONID。

      2. JSESSIONID在所有浏览器中都可以公用的。

        注:经测试,在登录时候service的并不仅仅起到登录成功后的跳转作用,如果使用的service是8888接口,用得到的jsessionid去8877配置了同样CAS Client的接口中访问时,会报错“未能识别xxxxxxx的票根”

  6. 网上学到一个方案。(参考链接放在最后)

    1. 粗略过程

      1. 前端访问登录接口,后端检测到未登录,然后修改代码不发出重定向的操作,并返回401和cas服务器地址,后面的背的serveice地址是自己的接口地址。
      2. 前端判断到401情况,在拿到url重定向之前,需要自己后面添加?url的参数,意为登录成功后跳转到的前端页面。
      3. 登录成功,跳转到后端接口上,后端进行判断,生成token等信息拼到url后面,让浏览器重定向到url页面。
      4. 前端只需要在进入此页面时候检测url是否有需要的信息即可,检测到了就达成登录。
    2. 详细过程:

      1. 前端访问登录,

      2. 后端进行拦截验证(第一次没有),本来是会给前端302重定向,由于前端是ajax无法识别302重定向,只会拦截下来,未做进一步的处理。我们修改这部分代码,返回json对象,code码定为401,data域中写入需要重定向的url且拼上登录成功需要跳转的接口。

      3. 前端处理接口返回内容,成功了就是登录成功了。若失败了并非是401错误时候,则会取data的数据进行重定向。

        这时候问题来了,前端手动重定向肯定是可以的,然后登录成功跳转到接口,可是接下来呢,跳转到的那个接口中总不能将数据直接返回去吧,这样就直接显示页面上面了。

        ​ 需要认识到的时候,现在是接口直接与浏览器打交道的,如果我们可以通过一种方式让浏览器重定向,可是重定向的网址呢,那就在重定向到cas服务器登录页之前就拼上去。

        然后再在后面添加?url=http://www.labalaba.com/login,意为登录成功后需要跳转的前端的页面。

      4. 跳转到cas服务器登录页,登录成功后跳转到参数service的地址(是我们后端的接口),接口验证内容,拿到用户消息,生成token或者个人信息,附到url后面。

      5. 接下来就是跳转到页面,上面也提到了,现在接口面对的是浏览器,并不是前端,不是ajax,所以我们可以使用下面这种方法进行重定向。

        @Controller
        public class UserController {
        /**
        * 在cas登录页登录成功进入此接口
        *
        * @param url 登录成功后要跳入的页面
        * @return 重定向,并在url后面拼接登录信息,如token等
        */
        @GetMapping("/redirect")
        public String redirect(@RequestParam String url) {
        return "redirect:" + url;
        }
        }
      6. 重定向到页面后,前端只需要在每次页面启动时候,检测地址栏中是否有想要的参数即可。

    3. 经过观察得出的结论:

      ​ 登录后cas server会返回一个ticket,然后在cas client的接口(service后面跟的)上验证成功后,生成一个JSESSIONID,存入浏览器的cookie中,且之后的接口中会放在Header中。所以service后面必须是接口。

      ​ 并非配置了拦截的接口才会去找cas server做验证,只要携带了,都会去做验证,且放在request中。所以只需要拦截/login(需要结合项目对于单点登录的需求),/redirect接口也回去找cas server做验证。

  7. 开始尝试, 修改过滤器AuthenticationFilter中的doFilter方法

  8. 覆盖的方法,也很简单,就只需要在/src/main/java/下创建AuthenticationFilter一样的包,然后创建同名类,将AuthenticationFilter中的内容全部覆盖,修改doFilter方法。

  9. 将最后一行this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);注释掉,不让它重定向,返回json数据。

    // add start // -------------------------------------------------
    
    PrintWriter out = response.getWriter();
    response.setContentType("application/json; charset=UTF-8");
    String http = "";
    String redirectUrl = serviceUrl;
    if (redirectUrl.contains("https://")) {
    http += "https://";
    redirectUrl = redirectUrl.substring(8);
    } else if (redirectUrl.contains("http://")) {
    http += "http://";
    redirectUrl = redirectUrl.substring(7);
    }
    int index = redirectUrl.indexOf("/"); String host = redirectUrl.substring(0, index + 1);
    String finalUrl = casServerLoginUrl+"?service="+http+host+"redirect"; System.err.println("拦截了 -- direct url: " + finalUrl); out.println(JSON.toJSON(new HashMap<String, Object>() {{
    put("code", "401");
    put("data", finalUrl);
    }})); out.flush();
    out.close(); // add end // -------------------------------------------------
  10. 分别是login接口和redirect接口。

    @ResponseBody
    @PostMapping("/login")
    public Object login(HttpServletRequest request) { AttributePrincipal principal2 = (AttributePrincipal)request.getUserPrincipal(); if (principal2 != null) { Map<String, Object> attrs = principal2.getAttributes(); log.info("login8888: " + attrs); return new HashMap<String, Object>() {{
    put("code", "200");
    put("msg", "8888登录成功");
    put("date", new HashMap<String, String>() {{
    put("accessToken", "-->wei_tiao_zhuan_suc");
    }});
    }};
    } log.error("login8888: null"); return "401, redirect to the cas server login url. by 8888";
    }

    redirect接口:

    @GetMapping("/redirect")
    public String redirect(@RequestParam String url, HttpServletRequest request) { AttributePrincipal principal2 = (AttributePrincipal)request.getUserPrincipal(); // 模拟jwt或者uuid生成token。 if (principal2 != null) {
    Map<String, Object> attrs = principal2.getAttributes(); log.info("登录成功,正在生成token");
    return "redirect:" + url + "?accessToken=-->tiao_zhuan_hou_suc"; } // 登录失败不返回token
    log.error("登录失败"); return "redirect:" + url;
    }
  11. 测试过程均是在两才电脑上,且登录接口是在element ui项目中访问的。

    序号 内容
    1 1个前端1个后端
    2 2个前端1个后端
    3 2个前端2个后端

    以上都为正常的,当测试到微服务️时候(参考资料中有位大佬也提到了):

    1. 场景: 1个前端,1个后端,但是后端是微服务,也即多模块,最后由网关进行转发。

      1. 网关端口8899,两个模块分别是8888和8877
      2. 这就限制了访问了login时候,必须使用8899端口,然后跳转cas登录。
      3. 成功后跳转的接口也得是8899的端口,但是不管找8888还是8877做验证,他们的端口都是8899,所以会验证失败。
    2. 讨论
      1. 微服务一般大型项目才会采用,所以基本会有个用户模块来控制所有模块的登录情况。
      2. 虽然这个问题基本上可以绕过,但是万一微服务项目需要用到别人的cas server时候到底如何处理呢。
      3. (等学习到了,会继续添加到这里。并删除这一行。)
  12. 参考(方案具体是参考的最后两个)

CAS前后端分离解决方案的更多相关文章

  1. [开源] angularjs + Asp.net 前后端分离解决方案

    本文版权归 博客园 萧秦 所有,此处为技术收藏,如有再转,请于篇头明显位置标明原创作者及出处,以示尊重! 作者:萧秦 原文:http://www.cnblogs.com/xqin/p/4862849. ...

  2. 前后端分离下的CAS跨域流程分析

    写在最前 前后端分离其实有两类: 开发阶段使用dev-server,生产阶段是打包成静态文件整个放入后端项目中. 开发阶段使用dev-server,生产阶段是打包成静态文件放入单独的静态资源服务器中, ...

  3. vue-element-admin改造接入后台,搭建有来商城youlai-mall前后端分离管理平台

    一. 前言 本篇基于有来商城youlai-mall微服务项目搭建的后台前端管理平台,技术选型Vue+Element-UI实现前后端分离,解决方案选型vue-element-admin.希望通过本篇你可 ...

  4. Spring Cloud 前后端分离后引起的跨域访问解决方案

    背景 Spring Cloud 微服务试点改造,目前在尝试前后端分离. 前台A应用(本机8080端口),通过网管(本机8769端口)调用后台应用B(本机8082端口).应用C发布的http服务.. A ...

  5. .Net Core与Vue.js模块化前后端分离快速开发解决方案(NetModular)

    NetModular是什么? NetModular不仅仅是一个框架,它也是一整套的模块化与前后端分离的快速开发的解决方案,目标是致力于开箱即用,让开发人员完全专注于业务开发,不需要关心底层封装和实现. ...

  6. 前后端分离使用 Token 登录解决方案

    前后端分离使用 Token 登录解决方案:https://juejin.im/post/5b7ea1366fb9a01a0b319612

  7. 前后端分离产生的跨域问题的解决方案之--jsonp、nginx代理、设置头信息等

    前言 在前后端没有分离的时候,前端开发要么是写静态页面,数据渲染后端来做,要么就是前端的页面和后端的代码刚开始的时候就合并在一起,每次后端代码更新了之后,前端也要更新一下代码,然后重启一下服务,还是比 ...

  8. 解决前后端分离的“两次请求”引出的Web服务器跨域请求访问问题的解决方案

    在前后端分离的项目中,前端和后端可能是在不同的服务器上,也可以是Docker上,那就意味着前端请求后端Restful接口时,存在跨域情况. 后端在做了通用的跨域资源共享CORS设置后,前端在做ajax ...

  9. Springboot+vue前后端分离项目,poi导出excel提供用户下载的解决方案

    因为我们做的是前后端分离项目 无法采用response.write直接将文件流写出 我们采用阿里云oss 进行保存 再返回的结果对象里面保存我们的文件地址 废话不多说,上代码 Springboot 第 ...

  10. Vue+elementui前后端分离,单个图片文件上传和上传时出现的跨域问题的解决方案

    在后端解决跨域问题: 我是通过配置文件来解决跨域问题的 @Configurationpublic class CorsConfig {//解决前后端分离的跨域问题! /** * cors suppor ...

随机推荐

  1. 微服务技术架构、监控、Docker、服务治理等详解

    1.什么是微服务 1)一组小的服务(大小没有特别的标准,只要同一团队的工程师理解服务的标识一致即可) 2)独立的进程(java的tomcat,nodejs等) 3)轻量级的通信(不是soap,是htt ...

  2. superset 相关视频(建议初学者开始刷2天视频,开眼界)

    建议集中一段时间刷视频,不用具体知道怎么操作,先明白能干什么,大概在那里弄,达到什么效果,是否符合自己的预期,然后再根据具体遇到的问题,再找视频 另外,看的时候注意有版本的不同,具体操作时候,版本不同 ...

  3. 使用Python的一维卷积

    学习&转载文章:使用Python的一维卷积 背景 在开发机器学习算法时,最重要的事情之一(如果不是最重要的话)是提取最相关的特征,这是在项目的特征工程部分中完成的. 在CNNs中,此过程由网络 ...

  4. MySQL5.7x 主从复制

    原文链接:https://blog.liuzijian.com/post/9f8ede8e-26de-75d6-6347.html 在MySQL中,主从复制(Master-Slave Replicat ...

  5. 类的内部成员之五:内部类(Person.Bird bird = p.new Bird();)

    /* * 类的内部成员之五:内部类 * 1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类 * * 2.内部类的分类:成员内部类(静态.非静态) vs 局部内部类(方法 ...

  6. 【技术美术】GPU渲染管线笔记

    [技术美术]GPU 渲染管线笔记 基本术语 基元.图面: 网格中所使用的顶点数据布局,常见的如点.线.三角面等,特殊的甚至包括一些带邻近基元的基元类型. 参数语义 语义是附加到着色器输入或输出参数的字 ...

  7. Qt QString的格式化与QString的拼接

    1. QString 与 QString 直接用 + 号也可以 QString date = "昨晚"; QString msg = "你真棒": QStrin ...

  8. 服务器vps测试脚本大全,新云linux综合工具箱-linux加速脚本 一键硬盘挂载

    服务器vps测试脚本大全 一键更换yum脚本 一键优化shh卡顿 一键更换软件源 各种linux加速 BBR原版 bbrplus 魔改plus 锐速 脚本linux加速脚本 一键硬盘挂载 一键cc防御 ...

  9. [Windows] 联发科秒开bl一键版(mtk)

    声明 不是所有的联发科都可 天机 8000 8100 9000等不行 已知 天机820 天机1000 mtk G90t 天机800 可以 其余自己测试 除了新款均可 第一步 下载软件 (是个压缩包需要 ...

  10. Hive - [01] 概述

    一.Hive是什么 是Facebook开源,用于解决海量结构化日志的数据统计工具. 是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能. Hive处理的数 ...