SpringSecurity系列之自定义登陆验证成功与失败的结果处理

1、须要自定义登陆结果的场景

在我以前的文章中,作过登陆验证流程的源码解析。其中比较重要的就是html

  • 当咱们登陆成功的时候,是由AuthenticationSuccessHandler进行登陆结果处理,默认跳转到defaultSuccessUrl配置的路径对应的资源页面(通常是首页index.html)。
  • 当咱们登陆失败的时候,是由AuthenticationfailureHandler进行登陆结果处理,默认跳转到failureUrl配置的路径对应的资源页面(通常是登陆页login.html)。

可是在web应用开发过程当中需求是变幻无穷的,有时须要咱们针对登陆结果作个性化处理,好比:web

  • 咱们但愿不一样的人登录以后,看到不一样的首页
  • 咱们应用是先后端分离的,验证响应结果是JSON格式数据,而不是页面跳转

以上的这些状况,使用Spring Security做为安全框架的时候,都须要咱们使用本节学到的知识进行自定义的登陆验证结果处理。spring

2、自定义登录成功的结果处理

为了知足上面的需求,咱们该如何去作呢?下面一小节咱们来讲明一下。AuthenticationSuccessHandler接口是Security提供的认证成功处理器接口,咱们只须要去实现它便可。可是一般来讲,咱们不会直接去实现AuthenticationSuccessHandler接口,而是继承SavedRequestAwareAuthenticationSuccessHandler 类,这个类会记住用户上一次请求的资源路径,好比:用户请求books.html,没有登录因此被拦截到了登陆页,当你万成登录以后会自动跳转到books.html,而不是主页面。json

@Component
public class MyAuthenticationSuccessHandler 
                        extends SavedRequestAwareAuthenticationSuccessHandler {

    //在application配置文件中配置登录的类型是JSON数据响应仍是作页面响应
    @Value("${spring.security.logintype}")
    private String loginType;

    private  static ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, 
                                        HttpServletResponse response, 
                                        Authentication authentication) 
                                        throws ServletException, IOException {

        if (loginType.equalsIgnoreCase("JSON")) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(AjaxResponse.success()));
        } else {
            // 会帮咱们跳转到上一次请求的页面上
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }
}
  • 在上面的自定义登录成功处理中,既适应JSON先后端分离的应用登陆结果处理,也适用于模板页面跳转应用的登陆结果处理
  • ObjectMapper 是Spring Boot默认集成的JSON数据处理类库Jackson中的类。
  • AjaxResponse是一个自定义的通用的JSON数据接口响应类。

3、自定义登陆失败的结果处理

这里咱们一样没有直接实现AuthenticationFailureHandler接口,而是继承SimpleUrlAuthenticationFailureHandler 类。该类中默认实现了登陆验证失败的跳转逻辑,即登录失败以后回到登陆页面。咱们能够利用这一点简化咱们的代码。后端

@Component
public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    //在application配置文件中配置登录的类型是JSON数据响应仍是作页面响应
    @Value("${spring.security.logintype}")
    private String loginType;

    private  static ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response, 
                                        AuthenticationException exception) 
                                        throws IOException, ServletException {

        if (loginType.equalsIgnoreCase("JSON")) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(
                    objectMapper.writeValueAsString(
                            AjaxResponse.error(
                                    new CustomException(
                                        CustomExceptionType.USER_INPUT_ERROR,
                                        "用户名或密码存在错误,请检查后再次登陆"))));
        } else {
            response.setContentType("text/html;charset=UTF-8");
            super.onAuthenticationFailure(request, response, exception);
        }

    }
}
  • 在上面的自定义登录失败处理中,既适应JSON先后端分离的应用登陆失败结果处理,也适用于模板页面跳转应用的登陆失败结果处理
  • 登录失败以后,将默认跳转到默认的failureUrl,即登陆界面。

4、配置SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Resource
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.csrf().disable() //禁用跨站csrf攻击防护,后面的章节会专门讲解
           .formLogin()
           .successHandler(myAuthenticationSuccessHandler)
           .failureHandler(myAuthenticationFailureHandler)
           .defaultSuccessUrl("/index")//登陆认证成功后默认转跳的路径
           .failureUrl("/login.html") //登陆认证是被跳转页面
}
  • 将自定义的AuthenticationSuccessHandler和AuthenticationFailureHandler注入到Spring Security配置类中
  • 使用fromlogin模式,配置successHandler和failureHandler。
  • 而且配置defaultSuccessUrl和failureUrl安全

    期待您的关注

  • 博主最近新写了一本书:《手摸手教您学习SpringBoot系列-16章97节》
  • 本文转载注明出处(必须带链接,不能只转文字):字母哥博客springboot

相关文章
相关标签/搜索