nginx反向代理cas應用實踐(多地址跳轉)

問題的提出:最近單位遇到一個需求,單位a和單位b,都經過專線鏈接到我單位,單位b提出須要訪問單位a網絡中的一個網站應用,原本很簡單問題,只須要我單位中一臺能夠訪問兩邊網絡的服務器上,架設nginx就能夠解決該問題,事實上,我天真了!html

(ps:本文僅針對對nginx反向代理有必定了解的朋友,如不瞭解請自行百度)前端

問題出如今這個網站應用上,他們使用了cas架構,在系統登陸的url地址和應用的地址不在一塊兒,以下:nginx

image

當使用系統的地址訪問時,他跳轉到下面的位置,顯示了登陸頁面:編程

image

當登陸系統後,又跳轉回192.168.20.150這個地址上。centos

查了一下cas,應該是用於登陸權限管理的。跨域

經過fiddle跟蹤,發如今使用http://192.168.20.164登陸時,返回了以下信息瀏覽器

image

 

紅線標出了,瀏覽器下次跳轉的url,繼續跳轉,返回:服務器

image

 

繼續跳,返回:cookie

image

 

到這裏,再跳轉到index.aspx就進入系統了。網絡

是否是有點暈!總結一下:

進入系統,一共進行了三次跳轉,系統的登陸首頁在192.168.20.164上面,點擊登陸成功後,就跳轉到192.168.20.150上面去。

能夠看出192.168.20.164是一個管理登陸的服務器,系統的真實服務器在192.168.20.150上面。

好了,大致狀況清楚了,但問題是如何實現咱們的需求呢??

一、經過網絡方式,開通兩邊的網絡,這樣確定應該是能夠,但太暴力了,也不容許,不現實,pass掉。

二、在中間服務器,使用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真的很方便,原先爲了實現反向代理、跨域,但是用編程實現的,唉。

相關文章
相關標籤/搜索