4.SpringSecurity自定义登录成功处理、显示登录失败信息、自定义登录失败处理、注销登录配置、前后端分离注销登录配置

自定义登录成功处理

有时候页面跳转并不能满足我们,特别是在前后端分离开发中就不需要成功之后跳转页面。只需要给前端返回一个 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 在登录失败之后会将异常信息存储到 requestsession作用域中 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 请求,路径为 /logout
  • invalidateHttpSession 退出时是否是 session 失效,默认值为 true
  • clearAuthentication 退出时是否清除认证信息,默认值为 true
  • logoutSuccessUrl 退出登录时跳转地址

前后端分离注销登录配置

如果是前后端分离开发,注销成功之后就不需要页面跳转了,只需要将注销成功的信息返回前端即可,此时我们可以通过自定义 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())
                //....................
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个双子座的Java攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值