8.退出登录
退出登录
1 2 3 | org.springframework.security.web.authentication.logout.LogoutFilter 匹配URL为/logout的请求,实现用户退出,清除认证信息。 |
只需要发送请求,请求路径为/logout即可, 当然这个路径也可以自行在配置类中自行指定, 同时退出 操作也有对应的自定义处理LogoutSuccessHandler,退出登录成功后执行,退出的同时如果有 remember-me的数据,同时一并删除
看一下 LogoutFilter 源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.security.web.authentication.logout; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.util.UrlUtils; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.filter.GenericFilterBean; public class LogoutFilter extends GenericFilterBean { private RequestMatcher logoutRequestMatcher; private final LogoutHandler handler; private final LogoutSuccessHandler logoutSuccessHandler; public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler, LogoutHandler... handlers) { this .handler = new CompositeLogoutHandler(handlers); Assert.notNull(logoutSuccessHandler, "logoutSuccessHandler cannot be null" ); this .logoutSuccessHandler = logoutSuccessHandler; this .setFilterProcessesUrl( "/logout" ); } public LogoutFilter(String logoutSuccessUrl, LogoutHandler... handlers) { this .handler = new CompositeLogoutHandler(handlers); Assert.isTrue(!StringUtils.hasLength(logoutSuccessUrl) || UrlUtils.isValidRedirectUrl(logoutSuccessUrl), () -> { return logoutSuccessUrl + " isn't a valid redirect URL" ; }); SimpleUrlLogoutSuccessHandler urlLogoutSuccessHandler = new SimpleUrlLogoutSuccessHandler(); if (StringUtils.hasText(logoutSuccessUrl)) { urlLogoutSuccessHandler.setDefaultTargetUrl(logoutSuccessUrl); } this .logoutSuccessHandler = urlLogoutSuccessHandler; this .setFilterProcessesUrl( "/logout" ); } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; if ( this .requiresLogout(request, response)) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if ( this .logger.isDebugEnabled()) { this .logger.debug( "Logging out user '" + auth + "' and transferring to logout destination" ); } this .handler.logout(request, response, auth); this .logoutSuccessHandler.onLogoutSuccess(request, response, auth); } else { chain.doFilter(request, response); } } protected boolean requiresLogout(HttpServletRequest request, HttpServletResponse response) { return this .logoutRequestMatcher.matches(request); } public void setLogoutRequestMatcher(RequestMatcher logoutRequestMatcher) { Assert.notNull(logoutRequestMatcher, "logoutRequestMatcher cannot be null" ); this .logoutRequestMatcher = logoutRequestMatcher; } public void setFilterProcessesUrl(String filterProcessesUrl) { this .logoutRequestMatcher = new AntPathRequestMatcher(filterProcessesUrl); } } |
默认退出路径 setFilterProcessesUrl("/logout");
发送 "/logout" 之后,退出完成之后没有指定的情况下会默认跳转到登录页面,如下源码:
代码实现如下:
index.html
1 2 3 4 5 6 7 8 | < div class = "header bg-main" > < div class = "logo margin-big-left fadein-top" > <h1>后台管理中心</h1> </ div > < div class = "head-l" > <a class = "button button-little bg-red" href= "/logout" > <span class = "icon-power-off" ></span>退出登录</a></ div > </ div > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package com.po.service.impl; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.DefaultRedirectStrategy; import org.springframework.security.web.RedirectStrategy; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.stereotype.Service; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Service public class MyAuthenticationService implements AuthenticationSuccessHandler, AuthenticationFailureHandler, LogoutSuccessHandler { RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); /** * 登录成功后的处理逻辑 * @param request * @param response * @param authentication * @throws IOException * @throws ServletException */ @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { System.out.println( "登录成功后继续处理。。。。。。。。" ); //重定向到index。html redirectStrategy.sendRedirect(request,response, "/" ); } /** * 登录失败后的处理逻辑 * @param request * @param response * @param exception * @throws IOException * @throws ServletException */ @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { System.out.println( "登录失败后继续处理。。。。。。。。" ); redirectStrategy.sendRedirect(request,response, "/toLoginPage" ); } @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { System.out.println( "退出之后继续处理。。。。" ); redirectStrategy.sendRedirect(request,response, "/toLoginPage" ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @Override protected void configure(HttpSecurity http) throws Exception { /** http.httpBasic() //开启httpBasic认证 .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问 */ /* http.formLogin().loginPage("/login.html")//开启表单认证 // .and().authorizeRequests() //放行登录页面 // .anyRequest().authenticated(); // .and().authorizeRequests().antMatchers("/login.html").permitAll() //放行登录页面 .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面 .anyRequest().authenticated();*/ http.formLogin() //开启表单认证 .loginPage( "/toLoginPage" ) // 自定义登陆页面 .loginProcessingUrl( "/login" ) //表单提交路径 .usernameParameter( "username" ).passwordParameter( "password" ) //自定义input额name值和password .successForwardUrl( "/" ) //登录成功之后跳转的路径 .successHandler(myAuthenticationService) // 登录成功处理 .failureHandler(myAuthenticationService) //登录失败处理 .and().logout().logoutUrl( "/logout" ) //退出 .logoutSuccessHandler(myAuthenticationService) //退出后处理 .and().authorizeRequests().antMatchers( "/toLoginPage" ).permitAll() //放行登录页面 .anyRequest().authenticated() .and().rememberMe() //开启记住我功能 .tokenValiditySeconds(1209600) //token失效时间,默认失效时间是两周 .rememberMeParameter( "remember-me" ) // 自定义表单name值 .tokenRepository(getPersistentTokenRepository()) //设置PersistentTokenRepository .and().headers().frameOptions().sameOrigin() //加载同源域名下iframe页面 .and().csrf().disable(); //关闭csrf防护 } |
测试结果
分类:
spring security
标签:
spring security
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY