Spring Security修炼手册(二)————Security的认证流程

Stella981
• 阅读 360

    那么通过第一节的介绍,大家对于Security认证的使用应该具备了一个基本的认识,那么这节主要有三个知识点。1、初步的带大家了解Security中几个过滤器(后面会一点点的加入其它过滤器)。2、表单认证的处理流程。3、如何自定义用户认证逻辑。那么废话不多说,直接进入第一点。

    哦!对了,我还要补充一点,有很多小伙伴私信我说,怎么能在用户完成认证之后,转跳到上一次请求的页面,我的回答是:So Easy!别配置defaultSuccessUrl就行了。

一、Spring Security中的过滤器

    通过第一节的介绍,大家应该知道Security是基于过滤器链的,那么它都有哪些过滤器?并且都是做什么的呢?下面一张图,为大家介绍几个初级的过滤器。

Spring Security修炼手册(二)————Security的认证流程

    那么spring security就是由这样一个过滤器链组成,在spring boot启动的时候被加载其中,每个过滤器负责校验不同的信息,最后的FilterSecurityIntercept是在前面的过滤器都校验通过的时候读取你对security的配置信息,比如是否为VIP才能访问等等,然后会抛出相应的异常,异常会被ExceptionTranslationFilter捕获,然后将不同异常对应的结果返回给前端。

    过滤器链上绿色的是可以通过配置来决定它生不生效,蓝色和黄色的是一定会执行,且必须按此顺序执行,开发人员不可更改的。在补充一下,别看蓝色的以Intercept结尾,但是他真的是一个过滤器,不是拦截器。

通过名字大家可以看出来两个绿色的过滤器一个是用户名密码认证过滤器,一个叫基本认证过滤器,那么当我们使用表单进行认证的时候,就是在usernamePasswordAuthticationFilter中进行处理的,我们先简单看一眼这个类中的代码:

Spring Security修炼手册(二)————Security的认证流程

二、表单认证的流程

    下面我们通过DeBug看一下,在输入用户名密码,点击登录后,在后台代码中到底发生了什么。首先我们在如下四个类中打上断点: UsernamePasswordAuthenticationFilter、ExceptionTranslationFilter、FilterSecurityIntercept、和我们的controller。

ExceptionTranslationFilter断点说明:

Spring Security修炼手册(二)————Security的认证流程

FilterSecurityInterceptor断点说明:

Spring Security修炼手册(二)————Security的认证流程

    打好断点后,我们执行登录操作。

Spring Security修炼手册(二)————Security的认证流程

    可以看到在在UsernamePasswordAuthenticationFilter中获取到了表单的用户名密码信息。而Security中提供了一个接口叫做UserDetailsService,这个接口非常简单只有一个方法,传进来的参数就是当前认证请求的用户名,返回值叫做UserDetails接口,这个UserDetails实则定义了当前用户的一些状态,如基本信息、是否可用、密码是否过期等等,那么因为我们现在还没有去具体的实现,所以都是走的Security默认的实现,后面我们会有自己的实现,在这里对比用户名密码OK后则通过第一步认证,然后走到FilterSecurityInterceptor,上一小节的图片中有介绍这个类中有一个对比配置的方法,那么我们先走进这个方法内,可以看到实则对我们要访问的URL进行了一次认证。

Spring Security修炼手册(二)————Security的认证流程

当我们有权限访问此URL时,则会执行我们的Controller

Spring Security修炼手册(二)————Security的认证流程

认证流程结束。

Spring Security修炼手册(二)————Security的认证流程

三、自定义认证逻辑

    在第二小节我们介绍了认证流程中用户名密码的对比等是在一个叫UserDetailsService的接口中实现,而  我们在第一章通过YML配置了一个内存用户,那么很明显,这样的方式并满足不了我们的业务需求,我们一般都是要把用户名密码权限这些信息放到数据库中,下面我来详细的介绍。

    我们先看一看UserDetailServer中的代码:

Spring Security修炼手册(二)————Security的认证流程

这个接口中只有一个方法,参数username就是表单中的用户名,我们可以通过用户名进行CURD的操作,返回值UserDetails同样也是一个接口,里面定义了用户名,密码,密码是否过期,账户是否可用等一系列的属性。

Spring Security修炼手册(二)————Security的认证流程

接下来我们具体实现一下:

@Component
public class MyUserDetailsServer implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        
        return new User(username, "$2a$10$ofPkBDUezOJp6Sik63Q/0.QlU8a1itEyzldjSXqfn2nDPqXjN0Ljm", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }

}

这个返回对象User是security给我们的默认实现,第一个参数就是传过来的用户名,第二个参数是通过用户名进行再数据库中查询到的密码(省略了数据库操作),第三个参数是从数据库中查询出来的当前用户拥有的权限(省略了数据库操作,直接使用工具类生成),由于我使用了加密密码,所以在SecurityConfig中需要将加密算法注入,代码如下:

Spring Security修炼手册(二)————Security的认证流程

如果想使用其他加密算法,实现PasswordEncoder接口即可。

这时候我们重启项目,用户名可以任意,密码为,123456a(上面密文对应的原文),这时候我的系统就拥有了自定义认证的功能。

Spring Security修炼手册(二)————Security的认证流程

Spring Security修炼手册(二)————Security的认证流程

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
4个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这