1. 程式人生 > >nginx反向代理cas應用實踐(多地址跳轉)

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

遇到 根據 ddl spa 每次 com war con 架設

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

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

問題出現在這個網站應用上,他們使用了cas架構,在系統登錄的url地址和應用的地址不在一起:如下

技術分享圖片

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

技術分享圖片


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

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

通過fiddle跟蹤,發現在使用http://192.168.20.164登錄時,返回了如下信息

技術分享圖片

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

技術分享圖片

繼續跳,返回:

技術分享圖片

到這裏,再跳轉到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,如下圖:

技術分享圖片

這時我們通~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真的很方便,原先為了實現反向代理、跨域,可是用編程實現的,唉。



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