CAS和Shiro内外网双IP动态访问

本文介绍了如何在内外网双IP环境中,使用CAS和Shiro实现动态单点登录和跳转。讨论了三种方案:Nginx反向代理、Nginx+Lua脚本以及后端动态修改URL。针对每个方案,分析了优缺点,并提供了相关资源链接。
摘要由CSDN通过智能技术生成

由于有需求要实现内外网双IP访问同一个应用,但是当前已部署的应用使用的cas+shiro的跳转url在spring的配置xml中写死的,所以需要实现判断来源HOST动态单点登录和跳转

部分响应体中写死了IP需要替换

使用Nginx+Lua脚本,body_filter_by_lua*替换响应体中的IP,也可以使用Nginx内置模块ngx_http_sub_filter_module ,或第三方模块replace-filter-nginx-module

因为替换内容后长度不一致了,需要在header_filter_by_lua*中加入ngx.header.content_length = nil置空内容长度

-- body_filter_by_lua_file:
-- 获取当前响应数据
local chunk, eof = ngx.arg[1], ngx.arg[2]
local cjson = require("cjson");

local req_headers = ngx.req.get_headers() -- 请求头
local resp_headers = ngx.resp.get_headers() -- 响应头

-- 定义全局变量,收集全部响应
if ngx.ctx.buffered == nil then
    ngx.ctx.buffered = {
   }
end

-- 如果非最后一次响应,将当前响应赋值
if chunk ~= "" and not ngx.is_subrequest then
    table.insert(ngx.ctx.buffered, chunk)
    -- 将当前响应赋值为空,以修改后的内容作为最终响应
    ngx.arg[1] = nil
end

-- 如果为最后一次响应,对所有响应数据进行处理
if eof then
    -- 获取所有响应数据
    local whole = table.concat(ngx.ctx.buffered)
    ngx.ctx.buffered = nil
    
    -- 内容有指定IP
    if whole
        -- 判断响应Host是否为客户端访问Host
        and not string.match(whole, ngx.var.http_host)
    then
        -- ngx.log(ngx.ERR, "body_filter_by_lua::::响应内容:》》》\n", whole, "\n《《《")
        -- 替换外网IP,需在server或location中设置以下两个变量
        -- set $outerIP "100%.100%.100%.100"; # 外网IP
        -- set $insideIP  "172%.16%.0%.91"; # 内网IP
        whole = string.gsub(whole, ngx.var.insideIP, ngx.var.outerIP)
        -- 重新赋值响应数据,以修改后的内容作为最终响应
    end
    ngx.arg[1] = whole
end

方案一

  • 使用Nginx反向代理

缺点很明显:登录CAS的URL中的service参数不能替换,而且无法做判断,可自定义程度不高

location /test {
    proxy_headers_hash_max_size 51200;
    proxy_headers_hash_bucket_size 6400;
    proxy_connect_timeout 500s;
    proxy_read_timeout 500s;
    proxy_send_timeout 500s;
    proxy_pass http://server/test;
    
    proxy_set_header Host $host:$server_port;
    #proxy_set_header Host $http_host;
    #proxy_set_header Host $server_addr:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # 修改响应头中的"Location"和"Refresh"字段,只能替换host部分,参数部分无法替换,非常重要
    # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
    #proxy_redirect $scheme://$server_addr:$server_port/ /;
    #proxy_redirect $scheme://$server_addr:$server_port/ $scheme://$http_host/;
    #proxy_redirect ~^http://172.16.0.1:81(.*) http://100.100.100.100:81$1; 
    proxy_redirect ~^http://172.16.0.91:81(.*) $scheme://$http_host$1;
    #proxy_set_header REMOTE-HOST $server_addr;
    proxy_set_header X-FORWARDED-HOST $server_addr;
    proxy_set_header X-FORWARDED-PORT $server_port;
    proxy_set_header Referer $http_referer;
    proxy_set_header Cookie $http_cookie;
    # response中set-cookie的domain转换
    #proxy_cookie_domain $server_addr $host; 
}

方案二

使用纯Nginx+Lua实现 lua-nginx-module时序图,点击链接后向上滑动

local uri_args = ngx.req.get_uri_args()
local outerIP = "100%.100%.100%.100"
local insideIP = "172%.16%.0%.91"
if uri_args["service"] then
    uri_args["service"] = string.gsub(uri_args["service"], outerIP, insideIP)
    ngx.req.set_uri_args(uri_args)
end

此方式可以使用Nginx全局变量实现,但可自定义程度范围不大

if ($is_args = "?"){
  
}
if ($arg_service){
    set $arg_service "http://172.16.0.91:81/test/login";
}
local resp_headers = ngx.resp.get_headers() -- 响应头
local resp_location = resp_headers.location -- 响应地址
local outerIP = "100%.100%.100%.100"
local insideIP = "172%.16%.0%.91"
if resp_location  ~= nil
    -- 判断响应Host是否为客户端访问Host
    and not string.match(ngx.header.location, ngx.var.http_host)
then
	ngx.header['location'] = string.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值