首页 > 代码库 > [JavaEE]记录一下反向代理下SSO不能正常使用的一个坑

[JavaEE]记录一下反向代理下SSO不能正常使用的一个坑

嗯...真的是很久没更新了,感觉有点瓶颈了,学又学不下去,工作要用的东西又没有难度,跳槽又没经验没学历关键是还不会吹也是尴尬...

无意间翻到这个博客,又是好久不更新突然想到了还有这个东西,就发一个最近做的小工具好了

 

主要是在做的某系统,客户哪里不愿意提供多端口,但是要部署多个应用和单点登录,于是就理所当然的用上了反向代理,然后就被公司内部的sso客户端给坑了...

 

SSO单点登陆一般思路应该是这样:

重定向到单点登录服务器 -> 服务器登陆成功跳回并带上身份标识 -> 项目二次前往单点登陆服务器校验身份并取回登陆信息 -> 设置登陆状态

 

本来是很简单的一件事,公司以前做过也都封装好了一个ssoclient.jar包,只要设置下过滤器继承一个登陆成功的回调类就可以了,使用起来简单粗暴,然而很微妙的是第一步就出了问题....公司之前写的ssoclient.jar在第一步,未登录时过滤器内重定向到单点登陆,而单点登陆系统要求提供一个地址参数用于登陆成功后跳回去,然而jar包内代码却写死了,通过request来获取当前服务器的协议、地址、端口,拼接后重定向了过去

 

然而这样就造成了一个问题,在反向代理环境下,request拿到的数据是反向代理内部的内网ip和端口,不是外网ip和端口,结果就是单点登录系统跳不回去了,对应的还是struts2配置的重定向,也有一样的问题,而且看了下ssoclient并没有代码,反编译出来还要搭建开发环境才能编译回去,太麻烦了

 

搜了搜,解决方案之一是两边同步配置,Nginx配置转发真实ip和端口,tomcat通过插件读取并设置到request中

不过很明显,能通过配置解决的问题....不够好玩儿啊....喜欢搞事情的我就真的继续搞事情了

 

其实思路和上面说的解决方案是一样的,通过tomcat插件配置真实地址到request中并不通用(其他容器配置方式不一样),而核心思路是篡改request里的getServerPort等几个方法返回真实的外网地址,而非反向代理内部地址

 

那么问题就变成了如何对request进行篡改,很明显servlet规范里肯定是不提供这样的功能了,于是我想了想...可以拿Filter搞事情啊,如果我的Filter是第一个进行操作的过滤器,并且提供一个假的request和reponse给后续过滤器操作,那么无论是struts2还是ssoclient,他们拿到的request和response都是我构造的,而非原始的

 

有了这个思路就好办了,定义两个request和response的转发类,对大部分真实方法进行转发,需要篡改的方法返回配置文件中配置的数据,然后对302重定向重新生成地址(原来的相对地址如果由交给tomcat之类的容器补全路径返回出去就会出错,路径会补充成反向代理的内网地址),然后就完事了

 

试了下效果挺好的,完美骗过了ssoclient和struts2,代码运行很正常,目前为止没遇到什么bug

 

代码地址:https://coding.net/u/pppploi8/p/MyUtils/git/tree/master/Java/RProxyFilter

也算是在这里顺便安利下自己的工具类项目玩儿玩儿好了....顺便随便看看还有没有人访问这个博客2333333

话说回来最近还在作死尝试搞一套前后台通用的参数校验工具类,等写好了有时间也放上来好了

[JavaEE]记录一下反向代理下SSO不能正常使用的一个坑