You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot3集成Shiro1.5.3时JWT过滤器不生效问题排查

问题:Spring Boot 3 + Shiro 1.5.3 自定义JWT过滤器未拦截请求

环境

  • Spring Boot 3
  • Shiro 1.5.3

问题详情

配置了基于JWT的Shiro自定义过滤器,但过滤器未按预期拦截请求,调试发现请求完全没有进入过滤器的isAccessAllowed()方法。

现有代码

ShiroConfig.java

@Configuration
public class ShiroConfig {
    // Other configurations...
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean("securityManager")
    public SecurityManager securityManager(UserRealm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        Map<String, Filter> map = new HashMap<>();
        map.put("jwt", new UserFilter());
        shiroFilter.setFilters(map);

        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/**", "jwt");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }
}

自定义过滤器UserFilter.java

@Slf4j
@Component
@Scope("prototype")
public class UserFilter extends BasicHttpAuthenticationFilter {
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws ServiceException {
        //...
    }
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        try {
            executeLogin(request, response);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

排查与解决建议

1. 版本兼容性问题

Shiro 1.5.3不支持Spring Boot 3(Spring Boot 3基于Spring Framework 6,要求Servlet 5.0+),版本不兼容会导致过滤器无法正常注册生效。直接升级Shiro到1.12.0及以上版本,该版本已完成对Spring Boot 3和Servlet 5的适配。

2. 手动注册Shiro过滤器

Spring Boot 3中,仅通过ShiroFilterFactoryBean创建Bean无法自动将Shiro过滤器注册到Servlet容器中,需要手动配置注册:

@Bean
public FilterRegistrationBean<ShiroFilter> shiroFilterRegistrationBean(@Qualifier("shiroFilter") ShiroFilterFactoryBean shiroFilterFactoryBean) throws Exception {
    FilterRegistrationBean<ShiroFilter> registrationBean = new FilterRegistrationBean<>();
    // 获取ShiroFilter实例
    ShiroFilter shiroFilter = (ShiroFilter) shiroFilterFactoryBean.getObject();
    registrationBean.setFilter(shiroFilter);
    // 设置最高优先级,确保Shiro最先拦截请求
    registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    // 匹配所有请求路径
    registrationBean.addUrlPatterns("/*");
    return registrationBean;
}

3. 修正自定义过滤器的实例化方式

你当前在配置中直接new UserFilter(),但UserFilter标注了@Component,这种混合方式会导致过滤器脱离Spring容器管理,丢失依赖注入或生命周期处理。改为从Spring容器注入:

@Configuration
public class ShiroConfig {
    // 注入Spring管理的UserFilter实例
    @Autowired
    private UserFilter userFilter;

    // ...其他Bean配置...

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        Map<String, Filter> map = new HashMap<>();
        // 使用Spring容器中的实例
        map.put("jwt", userFilter);
        shiroFilter.setFilters(map);

        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/**", "jwt");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }
}

4. 检查过滤器优先级

如果项目中存在其他全局过滤器(如Spring Security过滤器、自定义全局过滤器),优先级高于Shiro过滤器时会导致请求被提前处理。通过上述FilterRegistrationBean设置setOrder(Ordered.HIGHEST_PRECEDENCE)确保Shiro过滤器最先执行。

内容的提问来源于stack exchange,提问作者Alpha Beta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:58:12