当前位置 : 主页 > 编程语言 > python >

解决CAS 单点登录、iframe在最新版谷哥(99)Edge(99)等浏览器丢失的过程实记

来源:互联网 收集:自由互联 发布时间:2022-06-18
一、实记前言 各位看官你们好,经过上一篇我的文章​通篇的介绍以及铺垫,我相信您已经大概的知道了我们的应用场景了。下面继续介绍发现问题的过程以及如何解决我们遇到的问题

一、实记前言

各位看官你们好,经过上一篇我的文章​通篇的介绍以及铺垫,我相信您已经大概的知道了我们的应用场景了。下面继续介绍发现问题的过程以及如何解决我们遇到的问题。 先上一张图,让大家了解一下各个系统的情况。

解决CAS 单点登录、iframe在最新版谷哥(99)Edge(99)等浏览器丢失的过程实记_jar包

二、开发以及内测环境问题赘述

(一)开发环境

  • 集成cas单点登录 遇到casClient相关的jar包不加载
  • jar包加载了但是casClient客户端拦截不到用户的请求
  • 拦截到请求了,终于进入到登录环节了,但是输入对应的用户名以及密码以后后台报票根错误。
  • 票根错误解决完毕了,应该能正常的与casServer交互,并继续往下走,然后casServer返回对应的跳转地址url,但是此时B系统前端js无法获取casServer返回的url地址。
  • 不报票根错误了,但是登录成功以后到后应该跳转到我们系统的对应页面,但是浏览器直接显示了一段被它自己识别为普通字符串的html代码
  • (二)内测环境

  • 用户登录成功以后,点击A系统页面对应的按钮,正常的话应该是在他们的当前的页面中弹出一个弹窗,这个弹窗通过iframe 展示我们的页面,但是实际的现象确是浏览器直接打开了一个新的窗口,来展示我们的页面,这样导致了A系统的一个自动处置流程被迫中断
  • 点击A系统页面对应的按钮,在当前页面通过弹窗显示我们的页面以后,我们页面会调用后台接口,但是当时的现象是刨去没有以正确的方式打开我们的页面以外,页面调用我们后台接口时也报错。
  • 当解决完了让我们的页面在iframe里可以正确显示以后,新的问题又出现了,本应该嵌套显示的是我们对应的业务的页面,但是此时是显示的登录页面。也就是,用户已经登陆了一次了,应该直接跳转到我们业务页面,但是不知什么原因又被casClient拦截了,直接认定当前用户没有登录,跳转到了登录页。
  • 解决好了跳转登录页面以后以后本以为问题得到了解决,但是现实情况很打击人,本应该显示我们页面的地方死活不显示我们的页面,后来终于发现是浏览器的安全限制问题,如果用iframe 嵌套第三方页面,通过http请求方式访问第三方系统的时候,浏览器会禁止携带第三方的去请求对应的第三方系统,也就是所谓的丢失
  • 为了解决丢失问题,我们采取了https请求方式。结果问题依旧没有得到解决。此时陷入无解的境地。
  • 三、 开发以及内测环境遇到的问题解决方案(从此处开始上干货!!!!!!!)

    因为起初iframe采用的是http协议请求我们的系统。也就是在决定采取https协议之前。
    从此处开始着重挨个说明开发环境遇到的问题以及表现出的现象,以及对应的解决办法。还有内测环境遇到的问题以及表现出的还有对应的解决办法。
    开发环境如下:
    A系统页面代码(此处只是为了演示,真正的页面比下面展示的要复杂,而且采用的是动态的赋值给iframe 的src属性)

    <!DOCTYPE html>
    <html lang="zh" xmlns:th="http://www.thymeleaf.org" >
    <head>
    </head>
    <body class="" style="height: 700px;width: 1150px" >
    <div align="center" style="height: 600px;width: 1000px" >
    <iframe id="testPage" align="center" style="height: 500px;width: 850px"
    src="http://192.168.0.166:18080/accident/transmission/handle?devId=11111&bayId=22222&stId=33333&from=robot" about="about:blank" >
    </iframe>
    </div>
    <th:block th:include="include :: footer" />
    <script type="text/javascript">
    </script>
    </body>
    </html>
    复制代码

    nginx配置如下:

    events {
    worker_connections 1024;
    }

    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    underscores_in_headers on;
    server {
    listen 18080;
    server_name cyber.com;
    location / {
    root E:/WORKSPACE-DY/CyberMonitor-ui/dist;
    try_files $uri $uri/ /index.html;
    index index.html index.htm;
    }

    location /prod-api/ {
    proxy_set_header NGINX-REQEST-URL $host:$server_port/prod-api;
    proxy_set_header Host $host:$server_port;
    add_header Access-Control-Allow-Origin * always;
    add_header Access-Control-Allow-Credentials true;
    proxy_pass http://192.168.0.166:21080/;
    }

    }
    }
    复制代码

    Vue前端打包配置如下:

    ENV = 'production'
    VUE_APP_BASE_API = '/prod-api/'
    VUE_APP_BASE_LOGIN_API = '/prod-api/'
    复制代码

    (一)、开发环境遇到问题(用的是谷哥99版本浏览器,谷哥79版本浏览器,Edge99版本浏览器)

    • 1:集成cas单点登录 遇到casClient相关的jar包不加载

    问题原因:SpringBoot启动类未添加对应的casClient相关jar包的扫描路径配置:
    如下代码配置则导致容器扫描不到casClient的jar包

    @SpringBootApplication(
    exclude = { DataSourceAutoConfiguration.class })
    public class CyberApplication {
    public static void main(String[] args) {
    // System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(CyberApplication.class, args);
    }
    }
    复制代码

    对应的应该修改为下面的配置,com 是casClient jar包最外层的包名

    @SpringBootApplication(
    exclude = { DataSourceAutoConfiguration.class },
    scanBasePackages = {"com"})
    public class CyberApplication {
    public static void main(String[] args) {
    // System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(CyberApplication.class, args);
    }
    }
    //因为我们引入的cas是p平台团队修改过的,所以cas客户端的源码跟网络上开源的有稍微的区别
    复制代码
    • 2. cas客户端的jar包加载了但是casClient客户端拦截不到用户的请求

    该问题的原因如下,是因为我们采用的开源框架本身是为了前后端分离的方式量身定制的,有一定的局限性。但是p平台团队之前研发的单点登录系统虽然有微服务版本的,也支持SpringBoot,但是因为我们的开源框架请求头没有包含 X-Requested-With 这个请求头,但是casClient过滤器需要这个请求头进行逻辑判断,所以导致casClient过滤器无法拦截我们的请求。casClient部分源码如下:因为他是首先通过获取请求头中的X-Requested-With这个变量,然后继续后面的过滤操作。

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    HttpServletResponse response = (HttpServletResponse)servletResponse;
    String requestX = request.getHeader("X-Requested-With");
    if (!"XMLHttpRequest".equalsIgnoreCase(requestX)) {
    String queryStr = request.getQueryString();
    String url = request.getRequestURL().toString();
    if (url.contains("?")) {
    url = url.substring(0, url.indexOf("?"));
    }
    int tmep = url.indexOf(";jsessionid=");
    if (tmep > 0) {
    url = url.substring(0, tmep);
    if (!Util.isEmpty(queryStr)) {
    response.sendRedirect(url + "?" + queryStr);
    } else {
    response.sendRedirect(url);
    }
    return;
    }
    if (Util.isExcludePage(url)) {
    filterChain.doFilter(servletRequest, servletResponse);
    return;
    }
    HttpSession session = request.getSession(false);
    if (session != null && session.getAttribute("ssoWhiteURL") != null) {
    List<String> list = (List)session.getAttribute("ssoWhiteURL");
    if (list.contains(request.getRequestURI())) {
    filterChain.doFilter(servletRequest, servletResponse);
    return;
    }
    }
    if (!Util.isEmpty(queryStr)) {
    int index = queryStr.lastIndexOf("WT=");
    if (index >= 0) {
    session = request.getSession();
    if (session.getAttribute("ssoWhiteURL") == null) {
    List<String> whiteURL = new ArrayList();
    session.setAttribute("ssoWhiteURL", whiteURL);
    }
    ((List)session.getAttribute("ssoWhiteURL")).add(request.getRequestURI());
    if (index == 0) {
    response.sendRedirect(url);
    } else {
    response.sendRedirect(url + "?" + queryStr.substring(0, index - 1));
    }
    return;
    }
    }
    super.setCasServerLoginUrl(Util.findMatchingCasServerUrlPrefix(request) + "login");
    super.doFilter(servletRequest, servletResponse, filterChain);
    } else {
    super.setCasServerLoginUrl(Util.findMatchingCasServerUrlPrefix(request) + "login");
    super.doFilter(servletRequest, servletResponse, filterChain);
    }
    }


    【本文来源:香港将军澳机房 http://www.558idc.com/hk.html 欢迎留下您的宝贵建议】
    网友评论