一、报错信息:

1. CaptchaFilter.java(部分代码)

2. ShiroConfig.java(部分代码)

二、造成原因:

        没有保证过滤器单例。

三、解决方案:

方案一:使用静态类的方式

        RedisBean.java

@Component
public class RedisBean {
    @Autowired
    private RedisTemplate redisTemplate;

    public static RedisTemplate redis;
    @PostConstruct
    public void getRedisTemplate(){
        redis=this.redisTemplate;
    }
}

        CaptchaFilter.java

public class CaptchaFilter extends AccessControlFilter {
    //@Resource
    //private RedisTemplate<String,Object> redisTemplate;
    /**
     * 允许访问
     * @param servletRequest
     * @param servletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        HttpServletRequest request = WebUtils.toHttp(servletRequest);
        // 用户输入验证码
        String code = request.getParameter("code");

        // redis中的验证码
        String key = Constants.CAPTCHA_CODE_PREFIX + request.getParameter("uuid");
        RedisTemplate redisTemplate = RedisBean.redis;
        String realCode = (String) redisTemplate.opsForValue().get(key);

        if(realCode.equalsIgnoreCase(code)){
            // 验证码正确
            redisTemplate.delete(key);
            return true;
        }
        // 验证码错误
        redisTemplate.delete(key);
        return false;
    }

    /**
     * 拒绝访问
     * @param servletRequest
     * @param servletResponse
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        HttpServletResponse response = WebUtils.toHttp(servletResponse);
        // 响应格式-json串
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println(JSONUtil.toJsonStr(AjaxResult.fail("验证码错误!!!")));
        return false;
    }
}

方案二:将过滤器由spring管理

        方法一:使用@Component

    CaptchaFilter.java

        ShiroConfig.java

   @Resource
   private CaptchaFilter captchaFilter;
   @Bean
   public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        Map<String, Filter> filterMap = new HashMap<>();
        // 注意可以将多个过滤器交给spring托管,除非保证过滤器执行顺序
        filterMap.put("captchaFilter",captchaFilter);
        filterMap.put("jwtFilter",new JwtFilter());
        // filterMap中添加登出过滤器
        shiroFilterFactoryBean.setFilters(filterMap);
        Map<String,String> map = new HashMap<>();
        map.put("/captchaImage","anon");
        map.put("/login","captchaFilter");
        map.put("/refreshToken","anon");
        map.put("/logout","logout");
        map.put("/**","jwtFilter");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
   }

        方法二:使用@Bean

    CaptchaFilter.java

        ShiroConfig.java

    @Bean
    public CaptchaFilter captchaFilter(){
        return new CaptchaFilter();
    }
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        Map<String, Filter> filterMap = new HashMap<>();
        // 注意可以将多个过滤器交给spring托管,除非保证过滤器执行顺序
        filterMap.put("captchaFilter",captchaFilter());
        filterMap.put("jwtFilter",new JwtFilter());
        // filterMap中添加登出过滤器
        shiroFilterFactoryBean.setFilters(filterMap);
        Map<String,String> map = new HashMap<>();
        map.put("/captchaImage","anon");
        map.put("/login","captchaFilter");
        map.put("/refreshToken","anon");
        map.put("/logout","logout");
        map.put("/**","jwtFilter");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

注意:可以将多个过滤器交给spring托管,但要保证过滤器执行顺序,否则,会造成前端请求路径无效

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐