1.自定义filter
@Slf4j
public class ShiroFilter extends FormAuthenticationFilter {
@Autowired(required = false)
private RedisUtils redisUtils;
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
//这里只有返回false才会执行onAccessDenied方法,因为
// return super.isAccessAllowed(request, response, mappedValue);
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
String token = getRequestToken((HttpServletRequest) request);
String login = ((HttpServletRequest) request).getServletPath();
//如果为登录,就放行
if ("/bgUser/login".equals(login)){
log.error("放行");
return true;
}
if (EmptyUtil.isEmpty(token)){
log.error("没有token");
return false;
}
//从当前shiro中获得用户信息
BgUser user = (BgUser) SecurityUtils.getSubject().getPrincipal();
//拿到redis的token
String o = (String) redisUtils.get(user.getUserPhone());
// 一致直通过
if (o.equals(token)){
return true;
}else{
log.error("无效token");
}
return false;
}
private String getRequestToken(HttpServletRequest request){
//默认从请求头中获得token
return request.getHeader("token");
}
}
2.在shiro中使用自定义filter, 不用再对登录接口进行拦截,由自定义filter进行处理
@Component
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 设置自定义filter
Map<String, Filter> filter = new LinkedHashMap<>();
filter.put("auth", new ShiroFilter());
shiroFilterFactoryBean.setFilters(filter);
// 授权
Map<String,String> filterMap = new LinkedHashMap<>();
// 不用再对登录接口进行拦截,由自定义filter进行处理
filterMap.put("/**", "auth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManager
*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 创建Realm
*/
@Bean("userRealm")
public UserRealm userRealm(){
return new UserRealm();
}
}
3.验证
请求登录接口控制台打印结果,进行放行
请求其他接口,控制台打印需要token