今天在使用spring boot整合 shiro、jwt 實(shí)現(xiàn)前后端分離Token-Based身份認(rèn)證時(shí),自定義filter攔截除/login請求以外的所有請求。但是,最終/login也還是被攔截了。
@Bean
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
// 添加自己的過濾器并且取名為jwt
Map<String, Filter> filterMap = new HashMap<>();
//設(shè)置我們自定義的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;
}
在網(wǎng)上查閱資料,有人說是 filterChainDefinitionMap 不能使用HashMap,因?yàn)檫^濾器的執(zhí)行是有順序的,不能保證jwt過濾器是最后執(zhí)行,所以可能會把/login請求也攔截,所以這里要使用LinkedHashMap。
@Bean
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
// 添加自己的過濾器并且取名為jwt
Map<String, Filter> filterMap = new LinkedHashMap<>();
//設(shè)置我們自定義的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 并設(shè)置為未注冊狀態(tài)
filterRegistrationBean.setFilter(jwtAuthenticationFilter);
filterRegistrationBean.setEnabled(false);
return filterRegistrationBean;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager,
ShiroFilterChainDefinition shiroFilterChainDefinition,
FilterRegistrationBean filterRegistrationBean) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//設(shè)置SecurityManager
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//請求路徑,而非頁面路徑
//設(shè)置未授權(quán)訪問路徑
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
Map<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put("jwt", filterRegistrationBean.getFilter());
shiroFilterFactoryBean.setFilters(filterMap);
shiroFilterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());
return shiroFilterFactoryBean;
}