SpringSecurity5(4-自定义登录、登出处理器)

海哥  金牌会员 | 2025-3-14 09:31:30 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 954|帖子 954|积分 2862

自定义登录页面

常用方法

http.formLogin()

  • loginPage(String loginPage):设置用户登录页面的访问路径,默认为 GET 哀求的 /login
  • loginProcessingUrl(String loginProcessingUrl):设置登录表单提交的路径,默认为是 POST 哀求的 loginPage() 设置的路径
  • successForwardUrl(String forwordUrl):设置用户认证成功后转发的所在
  • successHandler(AuthenticationSuccessHandler successHandler):设置用户认证成功后的自定义处理器
  • defaultSuccessUrl(String defaultSuccessUrl):设置用户认证成功后重定向的所在。这里必要注意,该路径是用户直接访问登录页面认证成功后重定向的路径,如果是其他路径跳转到登录页面认证成功后会重定向到原始访问路径。可设置第二个参数为 true,使认证成功后始终重定向到该所在
  • failureForwrad(String forwardUrl):设置用户认证失败后转发的所在
  • failureHandler(AuthenticationFailureHandler authenticationFailureHandler):设置用户登录失败后的自定义错误处理器
  • failureUrl(String authenticationFailureUrl):设置用户登录失败后重定向的所在,指定的路径要能匿名访问,默认为 loginPage() + ?error
  • usernameParamter(String usernameParamter):设置登录表单中的用户名参数,默认为 username
  • passwordParamter(String passwordParamter):设置登录表单中的密码参数,默认为 password
使用案例
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>登录</title>
  6. </head>
  7. <body>
  8. <form  action="/login" method="post">
  9.    
  10.         <h3>账户登录</h3>
  11.         <input type="text" placeholder="用户名" name="username" required="required" />
  12.         <input type="password" placeholder="密码" name="password" required="required" />
  13.         <button type="submit">登录</button>
  14.    
  15. </form>
  16. </body>
  17. </html>
复制代码
  1. @Configuration
  2. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  3.     @Override
  4.     protected void configure(HttpSecurity http) throws Exception {
  5.         /**
  6.          * fromLogin():表单认证
  7.          * httpBasic():弹出框认证
  8.          * authorizeRequests():身份认证请求
  9.          * anyRequest():所有请求
  10.          * authenticated():身份认证
  11.          * loginPage():登录页面地址
  12.          * loginProcessingUrl():登录表单提交地址
  13.          * csrf().disable():关闭 Spring Security 的跨站请求伪造的功能
  14.          */
  15.         http.csrf().disable()
  16.                 .formLogin()
  17.                 .loginPage("/login.html")
  18.                 .loginProcessingUrl("/login")
  19.                 .and()
  20.                 .authorizeRequests()
  21.                 .antMatchers("/login.html").permitAll()
  22.                 .anyRequest()
  23.                 .authenticated();
  24.     }
  25. }
复制代码
注意:SpringBoot 项目集成 Spring Security 5.3.4RELEASE 后,默认环境 crsf 是开启的。每次哀求会校验哀求头中 X-CSRF-TOKEN 的值与内存中保存的是否一致,如果一致框架则认为登录页面是安全的,如果不一致,会报 403。
  1. @Controller
  2. public class LoginController {
  3.     @RequestMapping("/login.html")
  4.     public String login(){
  5.         return "login";
  6.     }
  7.     @RequestMapping("/test")
  8.     @ResponseBody
  9.     public String test(){
  10.         return "test";
  11.     }
  12. }
复制代码
转发
  1. http.formLogin()
  2.     .usernameParameter("name") // 设置请求参数中,用户名参数名称。 默认 username
  3.     .passwordParameter("pswd") // 设置请求参数中,密码参数名称。 默认 password
  4.     .loginPage("/toLogin") // 当用户未登录的时候,跳转的登录页面地址是什么? 默认 /login
  5.     .loginProcessingUrl("/login") // 用户登录逻辑请求地址是什么。 默认是 /login
  6.     .failureForwardUrl("/failure"); // 登录失败后,请求转发的位置。Security 请求转发使用 Post 请求。默认转发到:loginPage?error
  7.     .successForwardUrl("/toMain"); // 用户登录成功后,请求转发到的位置。Security 请求转发使用 POST 请求。
复制代码
重定向
  1. http.formLogin()
  2.     .usernameParameter("name") // 设置请求参数中,用户名参数名称。 默认 username
  3.     .passwordParameter("pswd") // 设置请求参数中,密码参数名称。 默认 password
  4.     .loginPage("/toLogin") // 当用户未登录的时候,跳转的登录页面地址是什么? 默认 /login
  5.     .loginProcessingUrl("/login") // 用户登录逻辑请求地址是什么。 默认是 /login
  6.     .defaultSuccessUrl("/toMain",true); //用户登录成功后,响应重定向到的位置。GET 请求。必须配置绝对地址。
  7.     .failureUrl("/failure"); // 登录失败后,重定向的位置。
复制代码
自定义登录处理器

AuthenticationSuccessHandler

用来处理认证成功的环境
  1. public interface AuthenticationSuccessHandler {
  2.     default void onAuthenticationSuccess(HttpServletRequest request,
  3.             HttpServletResponse response, FilterChain chain, Authentication authentication)
  4.             throws IOException, ServletException{
  5.         onAuthenticationSuccess(request, response, authentication);
  6.         chain.doFilter(request, response);
  7.     }
  8.     void onAuthenticationSuccess(HttpServletRequest request,
  9.             HttpServletResponse response, Authentication authentication)
  10.             throws IOException, ServletException;
  11. }
复制代码
  1. @Slf4j
  2. @Component
  3. public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
  4.     @Autowired
  5.     private ObjectMapper objectMapper;
  6.     @Override
  7.     public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
  8.         log.info("登录成功");
  9.         httpServletResponse.setContentType("application/json;charset=utf-8");
  10.         httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));
  11.     }
  12. }
复制代码
AuthenticationFailureHandler

用来处理认证失败的环境
  1. public interface AuthenticationFailureHandler {
  2.     void onAuthenticationFailure(HttpServletRequest request,
  3.             HttpServletResponse response, AuthenticationException exception)
  4.             throws IOException, ServletException;
  5. }
复制代码
  1. @Slf4j
  2. @Component
  3. public class AuthenticationFailureHandlerImpl implements AuthenticationFailureHandler {
  4.     @Autowired
  5.     private ObjectMapper objectMapper;
  6.     @Override
  7.     public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
  8.         log.info("登录失败");
  9.         httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
  10.         httpServletResponse.setContentType("application/json;charset=utf-8");
  11.         httpServletResponse.getWriter().write(objectMapper.writeValueAsString(e));
  12.     }
  13. }
复制代码
SimpleUrlAuthenticationSuccessHandler

用来处理认证成功后跳转的 URL 信息
  1. public class SimpleUrlAuthenticationSuccessHandler extends
  2.                 AbstractAuthenticationTargetUrlRequestHandler implements
  3.                 AuthenticationSuccessHandler {
  4.     public SimpleUrlAuthenticationSuccessHandler() {
  5.     }
  6.     public SimpleUrlAuthenticationSuccessHandler(String defaultTargetUrl) {
  7.         setDefaultTargetUrl(defaultTargetUrl);
  8.     }
  9.     public void onAuthenticationSuccess(HttpServletRequest request,
  10.             HttpServletResponse response, Authentication authentication)
  11.             throws IOException, ServletException {
  12.         handle(request, response, authentication);
  13.         clearAuthenticationAttributes(request);
  14.     }
  15.     protected final void clearAuthenticationAttributes(HttpServletRequest request) {
  16.         HttpSession session = request.getSession(false);
  17.         if (session == null) {
  18.             return;
  19.         }
  20.         session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
  21.     }
  22. }
复制代码
使用案例
  1. @Configuration
  2. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  3.     @Autowired
  4.     private AuthenticationSuccessHandlerImpl authenticationSuccessHandler;
  5.     @Autowired
  6.     private AuthenticationFailureHandlerImpl authenticationFailureHandler;
  7.    
  8.     @Override
  9.     protected void configure(HttpSecurity http) throws Exception {
  10.         /**
  11.          * fromLogin():表单认证
  12.          * httpBasic():弹出框认证
  13.          * authorizeRequests():身份认证请求
  14.          * anyRequest():所有请求
  15.          * authenticated():身份认证
  16.          * loginPage():登录页面地址
  17.          * loginProcessingUrl():登录表单提交地址
  18.          * csrf().disable():关闭 Spring Security 的跨站请求伪造的功能
  19.          */
  20.         http.csrf().disable()
  21.                 .formLogin()
  22.                 .loginPage("/login")
  23.                 .loginProcessingUrl("/auth/login")
  24.                 .successHandler(authenticationSuccessHandler)
  25.                 .failureHandler(authenticationFailureHandler)
  26.                 .and()
  27.                 .authorizeRequests()
  28.                 .antMatchers("/login").permitAll()
  29.                 .anyRequest()
  30.                 .authenticated();
  31.     }
  32. }
复制代码
自定义退出处理器

LogoutSuccessHandler

用来处理退出成功的环境
  1. public interface LogoutSuccessHandler {
  2.     void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
  3.             Authentication authentication) throws IOException, ServletException;
  4. }
复制代码
  1. @Component
  2. public class MyLogOutSuccessHandler implements LogoutSuccessHandler {
  3.     @Override
  4.     public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
  5.         httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
  6.         httpServletResponse.setContentType("application/json;charset=utf-8");
  7.         httpServletResponse.getWriter().write("退出成功,请重新登录");
  8.     }
  9. }
复制代码
SimpleUrlLogoutSuccessHandler

用来处理退出成功跳转的 URL 信息
  1. public class SimpleUrlLogoutSuccessHandler extends
  2.                 AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler {
  3.     public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
  4.             Authentication authentication) throws IOException, ServletException {
  5.         super.handle(request, response, authentication);
  6.     }
  7. }
复制代码
LogoutHandler
  1. http.and()
  2.     .logout() //提供系统退出支持,使用 WebSecurityConfigurerAdapter 会自动被应用
  3.     .logoutUrl("/logout") //默认退出地址
  4.     .logoutSuccessUrl("/login‐view?logout") //退出后的跳转地址
  5.     .addLogoutHandler(logoutHandler) //添加一个 LogoutHandler,用于实现用户退出时的清理工作.默认 SecurityContextLogoutHandler 会被添加为最后一个 LogoutHandler 。
  6.     .invalidateHttpSession(true);  //指定是否在退出时让 HttpSession 失效,默认是 true
复制代码
一般来说, LogoutHandler 的实现类被用来实行必要的清理,因而他们不应该抛出异常。
下面是 Spring Security 提供的一些实现:

  • PersistentTokenBasedRememberMeServices:基于持久化 token 的 RememberMe 功能的相关清理
  • TokenBasedRememberMeService:基于 token 的 RememberMe 功能的相关清理
  • CookieClearingLogoutHandler:退出时 Cookie 的相关清理
  • CsrfLogoutHandler:负责在退出时移除 csrfToken
  • SecurityContextLogoutHandler:退出时 SecurityContext 的相关清理
使用案例
  1. @GetMapping("/signout/success")
  2. public String signout() {
  3.     return "退出成功,请重新登录";
  4. }
复制代码
  1. @Configuration
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3.     @Autowired
  4.     private AuthenticationSuccessHandlerImpl authenticationSuccessHandler;
  5.     @Autowired
  6.     private AuthenticationFailureHandlerImpl authenticationFailureHandler;
  7.     @Resource
  8.     private MyLogOutSuccessHandler logOutSuccessHandler;
  9.     @Override
  10.     protected void configure(HttpSecurity http) throws Exception {
  11.         http.formLogin()
  12.             .successHandler(authenticationSuccessHandler)
  13.             .failureHandler(authenticationFailureHandler)
  14.             .and()
  15.             .logout()
  16.             //.logoutUrl("/signout")
  17.             .logoutSuccessUrl("/signout/success")
  18.             .deleteCookies("JSESSIONID")
  19.             .logoutSuccessHandler(logoutSuccessHandler)
  20.             .and()
  21.             .authorizeRequests()
  22.             .anyRequest()
  23.             .authenticated();
  24.     }
  25. }
复制代码
Spring Security 默认的退出登录 URL 为/logout,退出登录后,Spring Security 会做如下处理:

  • 使当前的 Session 失效
  • 清除与当前用户关联的 RememberMe 记录
  • 清空当前的 SecurityContext
  • 重定向到登录页


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表