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

本文介绍如何利用Nginx实现跨网络访问带有CAS认证系统的网站应用。通过详细配置示例,展示了如何解决登录过程中多次跳转的问题,并确保第三方网络能够正确访问目标系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题的提出:最近单位遇到一个需求,单位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真的很方便,原先为了实现反向代理、跨域,可是用编程实现的,唉。

 

 

1,tomcat8的配置: 1.1修改tomcat8.x/conf/context.xml的配置如下: <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- The contents of this file will be loaded for each web application --> <Context> <!-- Default set of monitored resources. If one of these changes, the --> <!-- web application will be reloaded. --> <WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource> <!-- Uncomment this to disable session persistence across Tomcat restarts --> <!-- <Manager pathname="" /> <Resources cachingAllowed="true" cacheMaxSize="100000" /> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:127.0.0.1:11211" username="root" password="" sticky="false" sessionBackupAsync="false" lockingMode="uriPattern:/path1|/path2" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> --> <Resources cachingAllowed="true" cacheMaxSize="100000" /> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:127.0.0.1:11211" username="root" password="" sticky="false" sessionBackupAsync="false" lockingMode="uriPattern:/path1|/path2" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" sessionBackupTimeout="18000" transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" copyCollectionsForSerialization="false" /> </Context> 1.2添加memcached如下依赖的jar包到tomcat8.x/lib/: asm-5.1.jar couchbase-client-1.4.12.jar javolution-5.5.1.jar kryo-4.0.0.jar kryo-serializers-0.38.jar memcached-session-manager-2.0.0.jar memcached-session-manager-tc8-2.0.0.jar minlog-1.3.jar msm-javolution-serializer-2.0.0.jar msm-kryo-serializer-2.0.0.jar msm-xstream-serializer-2.0.0.jar objenesis-2.1.jar reflectasm-1.09.jar spymemcached-2.12.1.jar 2,nginx的配置: #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; sendfile on; tcp_nopush on; tcp_nodelay on; #keepalive_timeout 0; keepalive_timeout 65; gzip on; #设定负载均衡的服务器列表 upstream 127.0.0.1 { #设定负载均衡的服务器列表 #ip_hash; #同一机器在多网情况下,路由切换,ip可能不同 #weigth参数表示权值,权值越高被分配到的几率越大 server 127.0.0.1:8085 weight=1 max_fails=20 fail_timeout=600s; server 127.0.0.1:8086 weight=1 max_fails=20 fail_timeout=600s; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name localhost; charset UTF-8; #设定本虚拟主机的访问日志 access_log logs/host.access.log main; #对 "/" 所有应用启用负载均衡 location / { proxy_pass http://127.0.0.1; #保留用户真实信息 proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; index index.html index.htm index.aspx; } #对 "/Dossm3RabbitMQConsumer/" 启用负载均衡 location /Dossm3RabbitMQConsumer/ { proxy_pass http://localhost:8086; #保留用户真实信息 proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; index index.html index.htm index.aspx; } } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} } 3,cas的配置(): 3.1 修改/CAS/WEB-INF/spring-configuration/ticketRegistry.xml <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to Jasig under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. Jasig licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at the following location: http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <description> Configuration for the default TicketRegistry which stores the tickets in-memory and cleans them out as specified intervals. </description> <!-- memcached 配置开始 --> <!-- Ticket Registry --> <bean id="ticketRegistry" class="org.jasig.cas.ticket.registry.MemCacheTicketRegistry"> <constructor-arg index="0"> <bean class="net.spy.memcached.spring.MemcachedClientFactoryBean" p:servers="127.0.0.1:11211" p:protocol="BINARY" p:locatorType="ARRAY_MOD" p:failureMode="Redistribute" p:transcoder-ref="serialTranscoder"> <property name="hashAlg"> <util:constant static-field="net.spy.memcached.DefaultHashAlgorithm.FNV1A_64_HASH" /> </property> </bean> </constructor-arg> <!-- TGT timeout in seconds --> <constructor-arg index="1" value="36000" /> <!-- ST timeout in seconds --> <constructor-arg index="2" value="2" /> </bean> <bean id="serialTranscoder" class="net.spy.memcached.transcoders.SerializingTranscoder" p:compressionThreshold="2048" /> <!-- memcached 配置结束 --> <!--Quartz --> <!-- 默认配置开始 --> <!-- Ticket Registry --> <!-- <bean id="ticketRegistry" class="org.jasig.cas.ticket.registry.DefaultTicketRegistry" />--> <!-- TICKET REGISTRY CLEANER --> <!-- <bean id="ticketRegistryCleaner" class="org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner" p:ticketRegistry-ref="ticketRegistry" p:logoutManager-ref="logoutManager" /> <bean id="jobDetailTicketRegistryCleaner" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" p:targetObject-ref="ticketRegistryCleaner" p:targetMethod="clean" /> <bean id="triggerJobDetailTicketRegistryCleaner" class="org.springframework.scheduling.quartz.SimpleTriggerBean" p:jobDetail-ref="jobDetailTicketRegistryCleaner" p:startDelay="200000" p:repeatInterval="50000000" /> --> <!-- 默认配置结束 --> </beans> 3.2 添加cas和memcached整合的如下依赖jar包到/CAS/WEB-INF/lib: cas-server-integration-memcached-4.0.0.jar mockito-core-2.1.0-RC.1.jar spymemcached-2.11.2.jar 参考CAS官方配置:https://apereo.github.io/cas/4.2.x/installation/Memcached-Ticket-Registry.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可能青蛙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值