shiro 中使用自定义filter后,给/login请求配置a

2023-09-13  本文已影响0人  南湘嘉荣

今天在使用spring boot整合 shiro、jwt 实现前后端分离Token-Based身份认证时,自定义filter拦截除/login请求以外的所有请求。但是,最终/login也还是被拦截了。

@Bean
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        // 添加自己的过滤器并且取名为jwt
        Map<String, Filter> filterMap = new HashMap<>();
        //设置我们自定义的JWT过滤器
        filterMap.put("jwt",new JwtFilter());
        factoryBean.setFilters(filterMap);
        
        Map<String,String> filterChainDefinitionMap = new HashMap<>();
        // 访问 /unauthorized 不通过JWTFilter
        filterChainDefinitionMap.put("/unauthorized","anon");
        filterChainDefinitionMap.put("/login","anon");
        // 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/**", "jwt");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return factoryBean;
}

在网上查阅资料,有人说是 filterChainDefinitionMap 不能使用HashMap,因为过滤器的执行是有顺序的,不能保证jwt过滤器是最后执行,所以可能会把/login请求也拦截,所以这里要使用LinkedHashMap。

@Bean
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        // 添加自己的过滤器并且取名为jwt
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        //设置我们自定义的JWT过滤器
        filterMap.put("jwt",new JwtFilter());
        factoryBean.setFilters(filterMap);
        
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 访问 /unauthorized 不通过JWTFilter
        filterChainDefinitionMap.put("/unauthorized","anon");
        filterChainDefinitionMap.put("/login","anon");
        // 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/**", "jwt");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return factoryBean;
}

但是,然而并没有什么用。

最终,如何使用 ShiroFilterChainDefinition 对象配置过滤器,并将自定义的 JwtAuthenticationFilter注册,就可以了。不过,在spring mvc中使用 Map 配置是可以的,不知道为什么 spring boot集成jwt不行。

@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
        defaultShiroFilterChainDefinition.addPathDefinition("/login","anon");
        defaultShiroFilterChainDefinition.addPathDefinition("/captchaImage","anon");
        defaultShiroFilterChainDefinition.addPathDefinition("/logout","anon");
        defaultShiroFilterChainDefinition.addPathDefinition("/favicon.ico","anon");
        defaultShiroFilterChainDefinition.addPathDefinition("/**","jwt");

        return defaultShiroFilterChainDefinition;
}

@Bean
public FilterRegistrationBean filterRegistrationBean(JwtAuthenticationFilter jwtAuthenticationFilter) {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        //添加JwtFilter  并设置为未注册状态
        filterRegistrationBean.setFilter(jwtAuthenticationFilter);
        filterRegistrationBean.setEnabled(false);

        return filterRegistrationBean;
}

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager,
                                           ShiroFilterChainDefinition shiroFilterChainDefinition,
                                           FilterRegistrationBean filterRegistrationBean) {

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        //请求路径,而非页面路径
        //设置未授权访问路径
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");

        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwt", filterRegistrationBean.getFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());

        return shiroFilterFactoryBean;
}
上一篇下一篇

猜你喜欢

热点阅读