方式一:使用系统过滤器
修改ShiroConfig,在filter表里加上登出的过滤:
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("dwSecurityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
//设置拦截后跳转的请求路径
factoryBean.setLoginUrl("/user/login");
首页
shiroFilterFactoryBean.setSuccessUrl("/index");
//错误页面,认证不通过跳转
factoryBean.setUnauthorizedUrl("/error");
//此处应该使用LinkedHashMap,否则会出现资源只能加载一次然后就被拦截的情况
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//不过滤
filterChainDefinitionMap.put("/showLogin", "anon"); // 登录页面,可匿名访问
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/goods", "anon"); // 首页,可匿名访问
// 访问401和404页面不通过我们的Filter
filterChainDefinitionMap.put("/401", "anon");
//filterChainDefinitionMap.put("/user/logout", "logout"); // 退出登录
//对所有用户认证
filterChainDefinitionMap.put("/**", "authc"); // 需登录才能访问
factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return factoryBean;
}
shiro会拦截/user/logout,并作出logout运作,完毕后会返回successUrl所拽定的index页面。
注:这种方式不需要在Controller中自定义退出相应的Mapping了
方式二:自定义controller路由实现
shiro的默认登出时会清理用户的session信息,并且也会清理掉 redis中缓存的用户身份认证
和权限认证
的相关信息。但有时候,我们可能还有自己的一些业务需要处理,比如限制用户的登录次数
、 并发登录的人数
或者记录日志 当前用户在线时长
,使用shiro默认登出方式是无法实现这些功能的。
如果登出操作中需要做额外的处理,可以自定义controller路由实现 :
@RequiresAuthentication
@GetMapping("/logout")
public Object logout() {
//在这里执行退出系统前需要清空的数据
Subject subject = SecurityUtils.getSubject();
if(subject.isAuthenticated()) {
subject.logout();
}
System.out.println("退出登录成功");
return ResultUtil.success("退出登录");
}