序
在写这篇文章之前,想了好长时间的题目该写什么,最后考虑到写这篇文章的目的,也就没有再起什么花哨的主题,而是找了这么一个简单粗暴有效的题目,方便有同样问题的童鞋们搜索。
背景
一如往昔,在谈这个问题之前,首先说说问题的背景所在。这个问题是前几天遇到的事,最近设计部给提了不少需求,于是一直在忙着实现这些需求,前几天说要发版,让提供一个新包供测试部进行全面的测试,其实,平常测试部也都在一直测着。发了新包之后,测试部给提了个 bug,可恨的是,这个 bug 在我本地却重现不了,因为我本地是没有这个问题的。当然,就是题目上说的错误了。
正文
在拿到这个问题之后,由于我本地的环境重现不了,而部署到 Linux 服务器上就会出现这个问题,这个让我比较郁闷,刚开始以为是环境的问题,后来发现不是。在网上查了查解决方案,怎么说的都有,但大都跟我这种情况不一样。我汇总了一下,大概有这几种情况。
第一种
Shiro 报这种错误 No SecurityManager accessible,说明是没有配置 shiroFilter,应该在 web.xml 中加入 shiroFilter 的配置。很显然,我的项目中 web.xml 已经配置了此 Filter,否则,在本地的时候就会报错了。当然,我也试了一下,如果把 shiroFilter 注掉的话,那么环境在启动的时候是不会报错的,但在访问的时候,就会报同样的错误。但是,跟我这种情况还不一样。因此,pass
掉。
第二种
Shiro 报这种错误 No SecurityManager accessible,第二种情况是,shiroFilter 已经配置了,但配置的参数有错误,对比了一下我这里的配置参数,发现也不太一样,所以,这种方式的解决方案也不适合我。只能继续找下一家了。
第三种
Shiro 报这种错误 No SecurityManager accessible,还有第三种情况,就是在 web.xml 中既配置了 shiroFilter ,也配置了 strutsFilter ,当然,出现这中问题的原因是 strutsFilter 放在了 shiroFilter 的前边,我们都知道,在
web.xml 中,Filter 的执行是按配置的顺序由上到下的,因此,在容器加载 web.xml 的时候,首先加载了 strutsFilter ,然后才会加载 shiroFilter 。
当然,这种情况是使用了 struts2,在 struts2 加载静态资源的时候,需要将 SecurityUtils 也加载进去,如果将 shiroFilter 的位置放到 strutsFilter 的后边,那么就会导致无法加载到 struts2 中去,而后在访问页面的时候,使用
SecurityUtils.getSubject() 的时候,导致出错。
但很可惜,我的环境中并没有用到 struts2,而是用的 springMVC 。很显然这一种也不怎么合适。不过这种方案倒是给了我一个启发,我在想,会不会是 Linux 服务器的环境中,在加载 web.xml 时,加载 Filter 的顺序上有问题,才会导致报这个错误呢。于是我就把
shiroFilter 的位置提到了 Filter 的最上边,重启 tomcat ,发现这个错误是没有了,但又报了一个 Session 失效的异常。
这下让我想到,我在 web.xml 中加入了一个拦截 Session 的 Filter ,这个 Filter 在 SecurityManager 中有用到,因此必须把 sessionFilter 放到第一位,然后是 shiroFilter ,这样发布到服务器上之后就没有问题了。
一点想法
到这还没完,让我想不通的是,为什么在我本地环境没有问题,而发布到 Linux 服务器上就会出问题,而且还不是每个服务器都这样,发布到另一个服务器上就没有问题,服务器的环境都是 Linux,发布的包也一样,tomcat 容器也没有问题,那么好了,问题到底出在哪?
其实,查了这么多,最后还没有想通,当然,对于解决问题来说,这个已经完成了,但是,对于为什么会出这样的问题而言,这似乎就不怎么够了。有遇到过相同情况的童鞋们,可以分享一下经验哈。我个人感觉,可能是由于 tomcat 的缓存,以及 shiro 的其他配置所导致的,当然,这仅仅是一个猜想,还没得到我的证实。
结束语
工作中经常会遇到一些很扯的问题,这些问题往往不是你改错了代码,改错了配置,而是什么都没动过,突然哪一天就出问题了,这对于我们来说是挺突然的,不过我要说的是,这种问题往往是潜在的问题没有被发现,哪一天突然就报出来了,当然,很好的测试能尽早的发现这种潜在的问题,不过,我要说的是,在开发的时候,尽量多注意一些,能避免的尽早避免。