• nginx反向代理cas应用实践(多地址跳转)


    问题的提出:最近单位遇到一个需求,单位a和单位b,都通过专线连接到我单位,单位b提出需要访问单位a网络中的一个网站应用,本来很简单问题,只需要我单位中一台可以访问两边网络的服务器上,架设nginx就可以解决该问题,事实上,我天真了!

    (ps:本文仅针对对nginx反向代理有一定了解的朋友,如不了解请自行百度)

    问题出现在这个网站应用上,他们使用了cas架构,在系统登录的url地址和应用的地址不在一起,如下:

    image

    当使用系统的地址访问时,他跳转到下面的位置,显示了登录页面:

    image

    当登录系统后,又跳转回192.168.20.150这个地址上。

    查了一下cas,应该是用于登录权限管理的。

    通过fiddle跟踪,发现在使用http://192.168.20.164登录时,返回了如下信息

    image

    红线标出了,浏览器下次跳转的url,继续跳转,返回:

    image

    继续跳,返回:

    image

    到这里,再跳转到index.aspx就进入系统了。

    是不是有点晕!总结一下:

    进入系统,一共进行了三次跳转,系统的登录首页在192.168.20.164上面,点击登录成功后,就跳转到192.168.20.150上面去。

    可以看出192.168.20.164是一个管理登录的服务器,系统的真实服务器在192.168.20.150上面。

    好了,大体情况清楚了,但问题是如何实现我们的需求呢??

    1、通过网络方式,开通两边的网络,这样肯定应该是可以,但太暴力了,也不允许,不现实,pass掉。

    2、在中间服务器,使用nginx反向代理,但常规的方式,显然满足不了当前的情况,如果浏览器根据响应返回的location跳转,就会访问不到了,只能看如何在响应头返回前端浏览器前,更改掉Location,让它继续指向我们自己的nginx服务器地址。

    所以,我安装一个台新的centos服务器在192.168.253.155上面,安装nginx 1.9.9,因为需要改变响应头中的Location值,需额外安装ngx_headers_more模块。

              在《nginx替换响应头(重点:如何在替换时加上if判断)》这篇文章中有详细的介绍。

    nginx.conf主要配置如下:

        map $upstream_http_Location $location{
            ~http://192.168.20.150/(?<param>.*) $param;
             default $upstream_http_Location;
        }

    ... ...

        server {
            listen       80;
            server_name  localhost;

            location /xt/ {
                 set $qz http://192.168.253.155/;
                 more_set_headers -s '302' 'Location:$qz$location';
                 add_header Cache-Control 'no-cache';
                 add_header Cache-Control 'no-store';

                 sub_filter  '/smportal-cas/'   '/xt/smportal-cas/';
                 sub_filter_once off;
                 proxy_pass http://192.168.20.164:XXXX/;
            }


           location / {
    ... ...
                 proxy_pass http://192.168.20.150/;
            }

    ... ...

    最上面的map用于将登录页面返回响应头中Location为的内容映射到变量$location中去,我们可以看到,在192.168.20.164上登录成功后,首先就跳转到http://192.168.20.150/xxx/xxx.aspx?ticket=xxxxxx,如下图:

    image

    这时我们通~http://192.168.20.150/(?<param>.*) $param;取出150/后面的内容(因为每次后面的内容会不同)赋到$location中。

    (注:(?<xxx> xxxx)是nginx中通过正则取值到变量的方法,此处首先赋值给了$param,然后通过map映射到$location。

    至于为什么不用$upstream_http_Location直接取值,用if判断呢?前面推荐的那篇文章写的很清楚。)

    接下来配置,将http://192.168.253.155/xt/的访问代理到http://192.168.20.164上面,让用户可以访问登录页面。

    其中

                 set $qz http://192.168.253.155/; #设置变量$qz为我们自己的地址
                 more_set_headers -s '302' 'Location:$qz$location'; #将$qz和$location(保存着刚才取到需跳转url的后面路径和参数部分)拼接成指向我们自己nginx的地址,即替换原先url中http://192.168.20.150为http://192.168.253.155

    最后配置http://192.168.253.155/的访问代理到http://192.168.20.150上面去,即完成了本次的任务。

    (ps: sub_filter的部分,是因为在登录页面中有很js,包括登录按钮提交时的url都使用了绝对的地址,所以需要在返回页面到前端前替换掉这些url,增加我们前辍/xt/,这样访问才没有问题。

        其实,实际情况中, 有很多的限制,比如单位b访问我单位的nginx服务器时,由于中间有网络设备不好调整,限制访问端口只能用80,而不能增加其它端口,所以配置只能使用子路径来区分多代理,本来可以用多端口就不用sub_filter替换内容了。

    在实验的过程中,也尝试过用代理登录的192.168.20.164服务器,用子路径xt代理系统服务器,最后引出了cookie的设置问题,虽最终没这样设,但发现nginx可以设置cookie的path,以保证代理时路径改变,cookie作对应的调整,特在此备注一下:

             proxy_cookie_path  /   /xt/;#将cookie的path的/映射为 /xt/

        感觉nginx真的很方便,原先为了实现反向代理、跨域,可是用编程实现的,唉。

  • 相关阅读:
    hihocoder 1049 后序遍历
    hihocoder 1310 岛屿
    Leetcode 63. Unique Paths II
    Leetcode 62. Unique Paths
    Leetcode 70. Climbing Stairs
    poj 3544 Journey with Pigs
    Leetcode 338. Counting Bits
    Leetcode 136. Single Number
    Leetcode 342. Power of Four
    Leetcode 299. Bulls and Cows
  • 原文地址:https://www.cnblogs.com/maybefrog/p/9336013.html
Copyright © 2020-2023  润新知