shiro的@RequiresPermissions不生效和无权限跳异常而不是shiro指定的无权页面

本文解决Shiro集成SpringMVC时遇到的问题,包括@RequiresPermissions注解不生效及无权限跳转异常而非指定页面。提供两种解决方案,并详细说明配置步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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来解决。

 

 

 

 

 

转载于:https://my.oschina.net/lenglingx/blog/1600118

### Filter 不生效的原因及解决方案 #### 原因分析 1. **注解配置问题** 使用 `@WebFilter` 注解时,如果未正确指定过滤器的路径匹配规则,则可能导致所有请求均被拦截,而不受注解中参数的控制。此情况通常发生在 Spring Boot 工程中,因为 `@WebFilter` 是 Servlet 容器级别的注解,默认情况下可能与 Spring 的上下文管理机制不完全兼容[^1]。 2. **Shiro 自定义 Filter 配置冲突** 在 Apache Shiro 中,当引入自定义 Filter 后,可能会覆盖默认的匿名访问 (`anon`) 过滤器行为,从而导致某些路径即使声明为无需认证也仍然受到拦截[^2]。 3. **核心配置文件加载失败** 如果项目的核心配置文件未能成功加载,也可能引发 Filter 不生效的问题。常见的原因包括但不限于以下几种: - 文件路径错误:系统尝试从错误的位置加载配置文件。 - 文件格式错误:例如 YAML 或 Properties 文件中的语法不符合规范。 - 参数名称或值错误:配置项的关键字拼有误或值不合理。 - 权限不足:程序无权读取配置文件。 - 环境变量缺失:依赖于特定环境变量来定位配置文件,但这些变量未设置或设置错误[^3]。 4. **Spring 上下文初始化异常** 若 Spring 应用启动过程中发生任何异常(如 Bean 初始化失败),可能导致部分组件(包括 Filter)未正常注册到容器中。 --- #### 解决方案 ##### 方法一:调整 @WebFilter 注解的使用方式 确保在使用 `@WebFilter` 注解时显式指定了 URL 模式以及过滤顺序等相关属性。例如: ```java import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; @WebFilter(filterName = "customFilter", urlPatterns = "/api/*", initParams = {@WebInitParam(name = "paramName", value = "paramValue")}) public class CustomFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 实现具体逻辑... chain.doFilter(request, response); } } ``` 此外,在 Spring Boot 项目中建议优先采用基于 Java Config 的方式替代单独使用 `@WebFilter` 注解,以更好地融入 Spring 生命周期管理。 ##### 方法二:修正 Shiro 自定义 Filter 导致 anon 失效的情况 对于 Shiro 场景下的问题,需重新梳理 Filter Chain 定义链路,确保新增加的自定义 Filter 不会干扰原有功能。以下是典型实现片段: ```java @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); Map<String, String> filterMap = new LinkedHashMap<>(); // 添加自定义过滤器前先保留原生支持的功能 filterMap.put("/login", "anon"); // 登录接口允许匿名访问 filterMap.put("/logout", "logout"); // 注销操作映射至 logout // 插入自定义过滤器实例并绑定对应 URI 路径 MyCustomFilter customFilterInstance = new MyCustomFilter(); bean.getFilters().put("myCustomFilter", customFilterInstance); filterMap.put("/secure/**", "myCustomFilter"); bean.setFilterChainDefinitionMap(filterMap); return bean; } ``` 注意此处通过编程形式精确设定每条规则的作用范围,避免全局泛化影响。 ##### 方法三:排查配置文件加载障碍 逐一验证是否存在上述提到的各种潜在隐患点,并采取针对性措施修复之。比如校验 application.yml 是否遵循标准书习惯;赋予必要目录适当的操作权限等。 ##### 方法四:捕获应用启动阶段的日志信息 利用调试工具观察整个流程是否有中断迹象,特别是关注那些标记为 WARN 或 ERROR 级别的提示语句。它们往往能够揭示隐藏较深的技术缺陷所在位置。 --- ### 总结 综上所述,造成 Filter 功能失效的因素多样复杂,既涉及框架本身的特性理解偏差,又牵扯外部条件配合不当等诸多方面。针对不同场景灵活运用以上策略可以有效缓解此类难题带来的困扰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值