一、需要自定义登录结果的场景

在我之前的文章中,做过登录验证流程的源码解析。其中比较重要的就是

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

但是在web应用开发过程中需求是千变万化的,有时需要我们针对登录结果做个性化处理,比如:

  • 我们希望不同的人登陆之后,看到不同的首页
  • 我们应用是前后端分离的,验证响应结果是JSON格式数据,而不是页面跳转

以上的这些情况,使用Spring Security作为安全框架的时候,都需要我们使用本节学到的知识进行自定义的登录验证结果处理。

二、自定义登陆成功的结果处理

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

@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数据接口响应类。

三、自定义登录失败的结果处理

这里我们同样没有直接实现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,即登录界面。

四、配置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节》
  • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

SpringSecurity系列之自定义登录验证成功与失败的结果处理的更多相关文章

  1. Spring Security 入门(3-11)Spring Security 的使用-自定义登录验证和回调地址

    配置文件 security-ns.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...

  2. CAS自定义登录验证方法

    一.CAS登录认证原理 CAS认证流程如下图: CAS服务器的org.jasig.cas.authentication.AuthenticationManager负责基于提供的凭证信息进行用户认证.与 ...

  3. SpringBoot20 集成SpringSecurity02 -> 利用SpringSecurity进行前后端分离的登录验证

    1 SpirngBoot环境搭建 创建一个SpringBoot项目即可,详情参见三少的相关博文 参考博文 -> 点击前往 SpirngBoot项目脚手架 -> 点击前往 2 引入Spirn ...

  4. Django自定义User模型和登录验证

    用户表已存在(与其他App共用),不能再使用Django内置的User模型和默认的登录认证.但是还想使用Django的认证框架(真的很方便啊). 两个步骤: 1)自定义Use模型,为了区分系统的Use ...

  5. Django学习系列之重写User模型和登录验证

    重写User模型 Django内置的User模型可能不适合某些项目,我们可能要基于内置的添加一些字段 创建users app startapp users 修改settings.py配置文件,覆盖默认 ...

  6. Spring Security登录验证流程源码解析

    一.登录认证基于过滤器链 Spring Security的登录验证流程核心就是过滤器链.当一个请求到达时按照过滤器链的顺序依次进行处理,通过所有过滤器链的验证,就可以访问API接口了. SpringS ...

  7. Spring Security框架进阶、自定义登录

      1.Spring Security框架进阶 1.1 Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安 ...

  8. 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)

    前言: shiro因为其简单.可靠.实现方便而成为现在最常用的安全框架,那么这篇文章除了会用简洁明了的方式讲一下基于spring的shiro详细配置和登录注销功能使用之外,也会根据惯例在文章最后总结一 ...

  9. koa使用koa-passport实现路由进入前登录验证

    现在的项目需求很简单,当进入一个页面的时候,如果没登录,则跳转到登录页面,如果登录了则直接到对应页面. koa2写的项目,使用koa-passport,koa-session,根据koa-passpo ...

随机推荐

  1. ES6入门之let和const命令

    前言 大家好,我是一只流浪的kk,当你看到这边博客的时候,说明你已经进入了ES6学习的领域了,从本篇博客开始,我将会将自己学习到ES6的相关知识进行整理,方便大家参考和学习,那么我将带你进入第一节的内 ...

  2. ssh-keygen创建证书

    ssh-keygen安装请参考以下内容:https://blog.csdn.net/a419419/article/details/80021684 (可能我已经安装过git了,所以不需要安装,具体细 ...

  3. opencv实践::直线检测

    问题描述 寻找英语试卷填空题的下划线,这个对后期的切图与自动 识别都比较重要. 解决思路 方法: 通过图像形态学操作来寻找直线,霍夫获取位置信息与显示. #include <opencv2/op ...

  4. nginx::配置https/反向代理

    vim /etc/nginx/nginx.conf user nginx; worker_processes ; error_log /var/log/nginx/error.log warn; pi ...

  5. (转)python中@property详解

    转:https://www.cnblogs.com/zhangfengxian/p/10199935.html

  6. spark cdh5编译安装[spark-1.0.2 hadoop2.3.0 cdh5.1.0]

    前提你得安装有Hadoop 我的版本hadoop2.3-cdh5.1.0 1.下载maven包 2.配置M2_HOME环境变量,配置maven 的bin目录到path路径 3.export MAVEN ...

  7. 说说Object类下面有几种方法呢?

    今天说一道基础题型,不过很多人会忽略或者至少说不完整,但是面试时被问到的几率还是很大的. 面试题 Object有几种方法呢? Java语言是一种单继承结构语言,Java中所有的类都有一个共同的祖先.这 ...

  8. 树莓派apt报错:E: '\Release' 这个值对 APT::Default-Release 是无效的,因为在源里找不到这样的发行

    E: '\jessie' 这个值对 APT::Default-Release 是无效的,因为在源里找不到这样的发行 开始尝试了各种方法, 换apt源, 改/etc/apt/apt.conf.d/10d ...

  9. java实现,使用opencv合成全景图,前端使用krpano展示

    这周花三天做了一demo,算上之前的,怎么也有五天,上一篇是opencv介绍,以及定义native方法,通过本地图片路径传参,底层调用Opencv图像库合成,有兴趣的可以看看,这篇重点在于krpano ...

  10. 像使用SQL一样对List对象集合进行排序

    在开始之前,我先卖个关子提一个问题:假设我们有一个Movie类,这个类有三个成员变量分别是starred(是否收藏), title(电影名称), rating(评分).你知道怎么对一个Movie对象组 ...