irpas技术客

4.SpringSecurity自定义登录成功处理、显示登录失败信息、自定义登录失败处理、注销登录配置、前后端分离注销登录配置_一个双子座的Java攻城狮

irpas 3014

自定义登录成功处理

有时候页面跳转并不能满足我们,特别是在前后端分离开发中就不需要成功之后跳转页面。只需要给前端返回一个 JSON 通知登录成功还是失败与否。这个时候可以通过自定义 AuthenticationSucccessHandler 实现

public interface AuthenticationSuccessHandler { /** * Called when a user has been successfully authenticated. * @param request the request which caused the successful authentication * @param response the response * @param authentication the <tt>Authentication</tt> object which was created during * the authentication process. */ void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException; }

根据接口的描述信息,也可以得知登录成功会自动回调这个方法,进一步查看它的默认实现,你会发现successForwardUrl、defaultSuccessUrl也是由它的子类实现的

自定义 AuthenticationSuccessHandler 实现 /** * 自定义认证成功之后的处理 */ public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler{ @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { Map<String,Object> result=new HashMap<>(); result.put("msg", "登录成功"); result.put("status", 200); response.setContentType("application/json;charset=UTF-8"); String s = new ObjectMapper().writeValueAsString(result); response.getWriter().println(s); } } 配置 AuthenticationSuccessHandler @Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() .mvcMatchers("/login.html").permitAll() .mvcMatchers("/index").permitAll()//放行资源写在任何前面 .anyRequest().authenticated() .and().formLogin() .loginPage("/login.html")//用来指定默认登录页面 注意:一旦自定义登录页面后必须只能登录url .loginProcessingUrl("/doLogin")//指定处理登录请求url .usernameParameter("uname") .passwordParameter("passwd") //.successForwardUrl("/index")//认证成功 forward 跳转路径 始终在认证成功之后跳转到指定请求 //.defaultSuccessUrl("/hello")//认证成功 redirect 如果之前请求路径,会有优先跳转之前请求路径 !!!! .successHandler(new MyAuthenticationSuccessHandler())//认证成功时处理 前后端分离时的处理方案 .and() .csrf().disable(); } }

运行并测试,可以发现前端返回json数据

显示登录失败信息

为了能更直观在登录页面看到异常错误信息,可以在登录页面中直接获取异常信息。Spring Security 在登录失败之后会将异常信息存储到 request 、session作用域中 key 为SPRING_SECURITY_LAST_EXCEPTION 命名属性中

显示异常信息 <div th:text="${session.SPRING_SECURITY_LAST_EXCEPTION}"></div> 配置 @Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() //............... .failureForwardUrl("/login.html")//认证失败之后 forward跳转 .failureUrl("/login.html")//认证失败之后 redirect跳转 //................ } }

failureUrl、failureForwardUrl 关系类似于之前提到的 successForwardUrl 、defaultSuccessUrl 方法

failureUrl 失败以后的重定向跳转failureForwardUrl 失败以后的 forward 跳转 注意:因此获取 request 中异常信息,这里只能使用failureForwardUrl

运行项目并测试

自定义登录失败处理

和自定义登录成功处理一样,Spring Security 同样为前后端分离开发提供了登录失败的处理,这个类就是 AuthenticationFailureHandler,源码为:

public interface AuthenticationFailureHandler { /** * Called when an authentication attempt fails. * @param request the request during which the authentication attempt occurred. * @param response the response. * @param exception the exception which was thrown to reject the authentication * request. */ void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException; }

根据接口的描述信息,也可以得知登录失败会自动回调这个方法,进一步查看它的默认实现,你会发现failureUrl、failureForwardUrl也是由它的子类实现的

自定义 AuthenticationFailureHandler 实现 public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { Map<String, Object> result = new HashMap<String, Object>(); result.put("msg", "登录失败: "+exception.getMessage()); result.put("status", 500); response.setContentType("application/json;charset=UTF-8"); String s = new ObjectMapper().writeValueAsString(result); response.getWriter().println(s); } } 配置 AuthenticationFailureHandler @Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() //...... .failureHandler(new MyAuthenticationFailureHandler()) //...... } }

注销登录

Spring Security 中也提供了默认的注销登录配置,在开发时也可以按照自己需求对注销进行个性化定制。

开启注销登录默认开启 @Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() //............. .successHandler(new MyAuthenticationSuccessHandler())//认证成功时处理 前后端分离时的处理方案 //.failureForwardUrl("/login.html")//认证失败之后 forward跳转 //.failureUrl("/login.html")//认证失败之后 redirect跳转 .failureHandler(new MyAuthenticationFailureHandler()) //................ .and() .logout() //.logoutUrl("/logout")//指定注销登录url .logoutRequestMatcher(new OrRequestMatcher( new AntPathRequestMatcher("/aa","GET"), new AntPathRequestMatcher("/bb","POST") )) .invalidateHttpSession(true)//默认 会话失效 .clearAuthentication(true)//默认 清除认证标记 .logoutSuccessUrl("/login.html")//注销登录 成功之后跳转页面 //.............. .and() .csrf().disable(); } } 通过 logout() 方法开启注销配置logoutUrl 指定退出登录请求地址,默认是 GET 请求,路径为 /logoutinvalidateHttpSession 退出时是否是 session 失效,默认值为 trueclearAuthentication 退出时是否清除认证信息,默认值为 truelogoutSuccessUrl 退出登录时跳转地址 前后端分离注销登录配置

如果是前后端分离开发,注销成功之后就不需要页面跳转了,只需要将注销成功的信息返回前端即可,此时我们可以通过自定义 LogoutSuccessHandler 实现来返回注销之后信息:

/** * 自定义注销成功之后处理 */ public class MyLogoutSuccessHandler implements LogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { Map<String, Object> result = new HashMap<String, Object>(); result.put("msg", "注销成功,当前认证对象为:"+authentication); result.put("status", 200); response.setContentType("application/json;charset=UTF-8"); String s = new ObjectMapper().writeValueAsString(result); response.getWriter().println(s); } } @Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() //................... .logoutSuccessHandler(new MyLogoutSuccessHandler()) //.................... } }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Spring