今天在使用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;
}
网友评论