Shiro 报错 No SecurityManager accessible(汇总)
该错误是在shiro-core中的SecurityUtils类里面报的,该类的作用是
Accesses the currently accessible Subject for the calling code depending on runtime environment.
该类有三个重要的方法
文档中对该方法的介绍
getSubject();这个方法就很熟悉了,就是我们在shiro中得到当前用户的方法;我们就是根据这个来跟shiro框架打交道的。
给shiro框架设置我们在xml文件中配置好的securityManager,在系统初始化AbstractShiroFilter的时候根据
staticSecurityManagerEnabled的值而将securityManager设置到SecurityUtils中。
如下图
staticSecurityManagerEnabled=true表示是将securityManager绑定给SecurityUtils,如果绑定了,那么我们就可以通过SecurityUtils直接访问到securityManager了,在shiro1.2.3中默认是false,也就是不给他绑定到SecurityUtils中;
每一个从shiroFilter进来的请求线程Thread,都会给其绑定一个SecurityManager,需要的时候,则获取该SecurityManager,从而获取对象
在网上查了查解决方案,大概有这几种情况。
第一种
Shiro 报这种错误 No SecurityManager accessible,说明是没有配置 shiroFilter,应该在 web.xml 中加入 shiroFilter 的配置。很显然,我的项目中 web.xml 已经配置了此 Filter,否则,在本地的时候就会报错了。当然,我也试了一下,如果把 shiroFilter 注掉的话,那么环境在启动的时候是不会报错的,但在访问的时候,就会报同样的错误。但是,跟我这种情况还不一样。因此,pass 掉。
第二种
Shiro 报这种错误 No SecurityManager accessible,第二种情况是,shiroFilter 已经配置了,但配置的参数有错误,对比了一下我这里的配置参数,发现也不太一样,所以,这种方式的解决方案也不适合我。只能继续找下一家了。
备注:我的问题就是这样的情况,只是配置了do请求进入shiroFilter,但是直接跳转到jsp的请求并没有经过shiroFilter,所以就到值直接跳转到jsp页面的时候,里面使用shiro相关的东西就不行了,因为这些请求没有让shiro管理。
第三种
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 ,这样发布到服务器上之后就没有问题了
ps:
下图中的DelegatingFilterProxy就是我们在web.xml中配置的shiroFilter的入口