Spring Security---退出功能详解
2023-04-18 14:29:38 时间
Spring Security---退出功能详解
logout退出登录
其实使用Spring Security进行logout非常简单,只需要在spring Security配置类配置项上加上这样一行代码:http.logout()。关于spring Security配置类的其他很多实现、如:HttpBasic模式、formLogin模式、自定义登录验证结果、使用权限表达式、session会话管理,。本节的核心内容就是在原有配置的基础上,加上这样一行代码:http.logout()。
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.logout();
}
}
加上logout配置之后,在你的“退出”按钮上使用/logout作为请求登出的路径。
<a href="/logout" >退出</a>
默认的logout做了什么?
虽然我们简简单单的实现了logout功能,是不是还不足够放心?我们下面就来看一下Spring Security默认在logout过程中帮我们做了哪些动作。
- 当前session失效,即:logout的核心需求,session失效就是访问权限的回收。
- 删除当前用户的 remember-me“记住我”功能信息
- clear清除当前的 SecurityContext
- 重定向到登录页面,loginPage配置项指定的页面
通常对于一个应用来讲,以上动作就是logout功能所需要具备的功能了。
个性化配置
虽然Spring Security默认使用了/logout作为退出处理请求路径,登录页面作为退出之后的跳转页面。这符合绝大多数的应用的开发逻辑,但有的时候我们需要一些个性化设置,如下:
http.logout()
.logoutUrl("/signout")
.logoutSuccessUrl("/aftersignout.html")
.deleteCookies("JSESSIONID")
- 通过指定logoutUrl配置改变退出请求的默认路径,当然html退出按钮的请求url也要修改
- 通过指定logoutSuccessUrl配置,来显式指定退出之后的跳转页面
- 还可以使用deleteCookies删除指定的cookie,参数为cookie的名称
演示
配置类:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private ObjectMapper objectMapper=new ObjectMapper();
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/css/**","/images/**");
}
//数据源注入
@Autowired
DataSource dataSource;
//持久化令牌配置
@Bean
JdbcTokenRepositoryImpl jdbcTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
return jdbcTokenRepository;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").hasRole("user")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html").permitAll()
.loginProcessingUrl("/login").permitAll()
.defaultSuccessUrl("/main.html")//可以记住上一次的请求路径
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setContentType("text/html;charset=utf-8");
httpServletResponse.getWriter().write("登录失败");
}
})
.and()
.logout()
//退出登录的请求,是再没退出前发出的,因此此时还有登录凭证
//可以访问
.logoutUrl("/logout")
//此时已经退出了登录,登录凭证没了
//那么想要访问非登录页面的请求,就必须保证这个请求无需凭证即可访问
.logoutSuccessUrl("/logout.html").permitAll()
.deleteCookies("JSESSIONID")
.and()
.rememberMe()
.key("dhy")
.tokenRepository(jdbcTokenRepository())
.and()
.csrf().disable();
}
//用户配置
@Override
@Bean
protected UserDetailsService userDetailsService() {
JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
manager.setDataSource(dataSource);
if (!manager.userExists("dhy")) {
manager.createUser(User.withUsername("dhy").password("123").roles("admin").build());
}
if (!manager.userExists("大忽悠")) {
manager.createUser(User.withUsername("大忽悠").password("123").roles("user").build());
}
return manager;
}
//角色继承
@Bean
RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_admin > ROLE_user");
return hierarchy;
}
}
点击退出登录:
回到设定的退出登录页面
LogoutSuccessHandler
如果上面的个性化配置,仍然满足不了您的应用需求。可能您的应用需要在logout的时候,做一些特殊动作,比如登录时长计算,清理业务相关的数据等等。你可以通过实现LogoutSuccessHandler 接口来实现你的业务逻辑。
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
//这里书写你自己的退出业务逻辑
// 重定向到登录页
response.sendRedirect("/login.html");
}
}
然后进行配置使其生效,核心代码就是一行logoutSuccessHandler。注意logoutSuccessUrl不要与logoutSuccessHandler一起使用,否则logoutSuccessHandler将失效。
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyLogoutSuccessHandler myLogoutSuccessHandler;
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.logout()
.logoutUrl("/signout")
//.logoutSuccessUrl(``"/aftersignout.html"``)
.deleteCookies("JSESSIONID")
//自定义logoutSuccessHandler
.logoutSuccessHandler(myLogoutSuccessHandler);
}
}
相关文章
- 实现多级缓存的架构设计方案
- 清华博士提出「Chiplet精算师」登顶会!越接近摩尔极限,多芯片集成越划算
- 90行代码!大一学生自学编程,自创搜题网站,已在GitHub开源
- Meta 拒绝使用高通芯片,并质疑其配套软件不够成熟
- 新一代数据基础设施:数据智能平台(附下载)
- 被奖12万!凌晨发现实验室漏水,中科大5学生踹门救下2400万设备和九章三号
- Transformer 自然语言处理简介
- 开价20w美元,这家公司想买下你的脸!不限性别年龄,预计2023年投入机器人使用
- Gartner公布首个SSE魔力象限排名
- 众筹十万美元搞火箭,搞研发全靠志愿者!这个“草根”航天组织已经开启载人测试
- 敏捷开发:从理论到团队落地
- 20年老码农分享20条编程经验,你pick哪些?
- 人工智能,“抛弃”真实数据集?
- 实战 | OpenCV如何将不同轮廓合并成一个轮廓(附源码)
- 认识ArcGIS Pro
- 谷歌下一代AI架构、Jeff Dean宣传大半年的Pathways终于有论文了
- 实战 | 文本图片去水印--同时保持文本原始色彩(附源码)
- 小学生们在B站讲算法,网友:我只会阿巴阿巴
- 涨姿势!OpenCV对比度亮度变换竟能用来去水印(附Python/C++源码)
- AI分析手机实现精准扶贫:伯克利研究登上Nature