一个单点登录问题的解决
上周五的时候,一个同事问我一个单点登录的问题 。整个系统结构并不复杂,在webapp应用中配置一个sso应用的servlet 过滤器 ,这个过滤器会从指定的域名下拿cookie中保存的一个加密sessionid ,利用这个sessionid到sso系统中判断是否登录以及是否在登录有效期内,未登录则进入登录页面,登录成功后,通过一个浏览器的302重定向进入目标页面。
同事反映,正常登录以后进入的目标页面,地址不对,我看了一下, 是目标主机的端口号丢失了。于是我在本地搭建了一个测试环境,启动tomcat进行测试,发现并没有出现类似的问题,debug到源码发现目标页面URL也是正确的,继续debug源码,发现sso的servlet过滤器使用的是httpservletRequest获取到http请求的hostname,port,requestURI的。
这时, 我又分析同事的maven 依赖的sso 二方包版本是否和我的一致, 也没有问题。
进一步分析应用部署环境的差异, 发现同事的环境使用了nginx + tomcat的架构, 采用nginx做了一层负载均衡代理,于是查看webapp获取到的requestURL,发现根本就没有浏览器发送的原始URL中的端口。问题就在于此, 浏览器发送的请求是交给nginx,而nginx转发请求给tomcat时,端口号已经丢失掉了, 所以依赖于这个URL拼接出来的目标页面URL自然也就不对了。进一步看sso Filter 的配置项,是专门有针对主机端口的配置项的。
这个问题的解决提醒我们,在查找问题时,系统部署环境的差异往往是解决问题的一个关键,特别是在很多问题从代码本身找不到原因的时候。