shiro和springmvc结合时需要关注的2个问题

一个是shiro的@RequiresPermissions不生效
一个是无权限跳异常而不是shiro的无权指定页面错误页面

 

applicationContext-shiro.xml中的关于过滤链的配置:

 

一、 shiro的@RequiresPermissions不生效

产生原因:由于fillter是在spring容器中,而不是在springmvc容器中,所以不起作用。

解决方法1:

在spring-mvc.xml中最前面(最先加载)添加如下:

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
        depends-on="lifecycleBeanPostProcessor" />
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
</bean>

lifecycleBeanPostProcessor和securityManager是在shiro配置文件中定义好的。
可以放在applicationContext-shiro.xml,然后又applicationContext.xml通过import方式导入。

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>

<!-- Shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="jdbcRealm"></property>
    <property name="cacheManager" ref="cacheManager"></property>
</bean>

解决方法2:

就是controller层不使用shiro的@RequiresPermissions注解,放到对应的service层去。这个感觉不是很好。应该使用解决方法1。

 

二、 shiro无权限异常出现到页面上了,而不是shiro指定的无权访问的页面

产生的原因:

shiro的源代码ShiroFilterFactoryBean.Java定义的filter必须满足filter instanceof AuthorizationFilter,只有perms,roles,ssl,rest,port才是属于AuthorizationFilter,而anon,authcBasic,auchc,user是AuthenticationFilter,所以unauthorizedUrl设置后页面不跳转 
Shiro注解模式下,登录失败与没有权限都是通过抛出异常。并且默认并没有去处理或者捕获这些异常。在SpringMVC下需要配置捕获相应异常来通知用户信息

通过看配置文件可以看到,filter过滤链的最后是/** = authc 。

一般我们访问的这个路径也在authc这个过滤器处理中,他是AuthenticationFilter(认证过滤链),不是AuthorizationFilter(授权过滤链)。

解决方法1:

既然shiro的配置没有用了,那么就要来找找springmvc中能不能解决这个问题了。
springmvc中有一个org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类就可以解决这个问题,我们在spring-mvc.xml配置文件中配置一个bean,如下:

<bean  
    class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
    <property name="exceptionMappings">  
        <props>  
            <prop key="org.apache.shiro.authz.UnauthorizedException">  //表示捕获的异常
                /unauthorized  //捕获该异常时跳转的路径
            </prop>  
            <prop key="org.apache.shiro.authz.UnauthenticatedException">  //表示捕获的异常
                /unauthenticated  //捕获该异常时跳转的路径
            </prop>  
        </props>  
    </property>  
</bean> 

这样就可以把授权时没有权限时报的异常通过springmvc的来处理到相应的页面。

解决方法2:

就是从问题产生的原因来解决,应为我们这个请求的页面是通过 /** = authc 来匹配了,就是通过认证(登录)过滤链来处理,改成perms或者roles 来匹配就好了。

但是由于这样的授权路径比较多,建议使用方法1来解决。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐