登陆认证框架:SpringSecurity
最近想给自己的小系统搭建一个登录认证服务,最初是想着一套oauth2权鉴就可以,但是发现这个oauth2只是权鉴,具体的登录认证需要由 SpringSecurity来进行实现。
也就是说SpringSecurity 主要就是用来进行用户名、密码认证的登录框架
然后看了一下 SpringSecurity,发现之前用过,但是只是用过,具体的流程不清楚。
趁这个机会,将SpringSecurity源码大体的整理看一下。
概述
SpringSecurity 的功能就是 认证、授权、防止伪造登录
其核心就是一组过滤链,通过各种的过滤器对请求进行过过滤,然后放行符合规则的请求。
具体流程可以看下图:

流程
从上面我们可以清楚的认知到,我们的请求是由多个过滤器过滤之后才能访问到具体的api 的,那么各个过滤器是怎么进行的合作的呢?
这章只说登录认证

1. AbstractAuthenticationProcessingFilter 过滤器
首先是 SpringSecurity一系列过滤器,然后走到AbstractAuthenticationProcessingFilter 这个过滤器,这个过滤器就是一个模版,主要是用来进行 识别是否是 认证请求,然后将不是认证请求到给到下一个过滤器的实现类(就是一组过滤器的串联)
这个过滤器中,主要的是doFilter方法,这个方法中requiresAuthentication 识别是否是认证请求,如果是,那么交给 attemptAuthentication 这个方法去处理,但是attemptAuthentication方法是抽象方法,需要子类去实现,然后我们就找到UsernamePasswordAuthenticationFilter 过滤器,也就是attemptAuthentication方法的具体实现类,也就是AbstractAuthenticationProcessingFilter的子类。
流程可以看图
2. UsernamePasswordAuthenticationFilter 过滤器
它实际上是处理 认证请求的过滤器,AbstractAuthenticationProcessingFilter的子类,真正实现类attemptAuthentication方法。
attemptAuthentication方法中,除了进行对请求中用户名、密码参数的处理外,核心的一行是this.getAuthenticationManager().authenticate(authRequest); 这个就是用 选择合适的 验证类来进行验证,从名称我们也能看出AuthenticationManager 是一个管理类,这个里面有多个AuthenticationProvider 对象。选择合适的验证就行。
但是这个getAuthenticationManager是一个接口,需要找到真正的实现类才行。
流程可以看图
3. ProviderManager 管理类
这个类就是真正选择具体的认证 类,authenticate方法遍历认证类,然后将请求中的用户名、密码进行验证的。
从上图可以看到,它就是对所有的认证类遍历,选择合适的进行。
provider.authenticate(authentication); 就是它的方法的核心代码。
但是AuthenticationProvider 也是一个接口,需要找其真正的实现类。
4. AbstractUserDetailsAuthenticationProvider(抽象类)
authenticate 方法的具体实现是AbstractUserDetailsAuthenticationProvider类实现的。
我们具体看authenticate 方法,然后发现这个方法,就是先去内存中检查,是否有这个用户名 和密码,如果没有在去调用retrieveUser方法,查找这个 用户名 和密码。

然后找到之后,在去调用additionalAuthenticationChecks 方法去验证 持久化中的(内存或者retrieveUser方法找到的用户名和密码)是否和请求中的用户名密码一致,如果是一致的,那么就调用additionalAuthenticationChecks 方法去验证。
但是retrieveUser 和 additionalAuthenticationChecks 方法都是抽象方法,具体的实现,是子类进行的。
5. DaoAuthenticationProvider(子类)
这个是AbstractUserDetailsAuthenticationProvider 的子类,实现了retrieveUser 和 additionalAuthenticationChecks 方法,我们可以看到两个方法:

注意看 this.getUserDetailsService().loadUserByUsername(username); 这个方法不就是我们自定义 获取真正的(也就是持久化 中)用户名 和 密码 时需要重写的方法么,返回的user 类,不就是UserDetails 这个类的子类么。
而且,我们在看additionalAuthenticationChecks 这个方法,不就是调用PasswordEncoder 类中的matches 方法去对比的么

至此,我们就将 SpringSecurity 用户登录验证流程走通了。
我们将这个进行一个串联
6. 串联

这里我们就将 SpringSecurity 中 用户验证 流程串联完成了,我们依据这个可以写定制一个流程去进行。下一章是 SpringSecurity 认证的 实践。
登陆认证框架:SpringSecurity的更多相关文章
- spring-security 登陆认证之初次探究
首先,希望还对 spring-security框架完全不懂的新手 下载下Git源码. 引入到项目中.这个短文就是边看源码边聊的.也会启动下项目验证自己的推想. 一.登陆认证的登陆配置项 <for ...
- 登陆模块,这个是很重要的模块,有shiro和spring security专门的权限认证框架
登陆模块,这个是很重要的模块,有shiro和spring security专门的权限认证框架
- Spring集成shiro做登陆认证
一.背景 其实很早的时候,就在项目中有使用到shiro做登陆认证,直到今天才又想起来这茬,自己抽空搭了一个spring+springmvc+mybatis和shiro进行集成的种子项目,当然里面还有很 ...
- {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证
Django基础九之中间件 本节目录 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证 六 xxx 七 xxx 八 xxx 一 前戏 我们在前面的课程中已经学会了 ...
- API代理网关和OAuth2.0授权认证框架
API代理网关和OAuth2.0授权认证框架 https://www.cnblogs.com/bluedoctor/p/8967951.html 1,授权认证与微服务架构 1.1,由不同团队合作引发的 ...
- Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理
本文是接着上篇博客写的:Spring boot 入门(三):SpringBoot 集成结合 AdminLTE(Freemarker),利用 generate 自动生成代码,利用 DataTable 和 ...
- 有登陆认证的情况下如何使用Wisdom RESTClient?
访问REST API时,很多系统需要登陆认证,登陆成功以后才允许访问API.下面介绍一下有登陆认证情况下如何使用 Wisdom RESTClient测试API的方法. 方法很简单即在浏览器上成功登录系 ...
- django-rest-framework登陆认证
# -*- coding: utf-8 -*- __author__ = 'YongCong Wu' # @Time : 2018/10/23 15:05 # @Email : : 192287802 ...
- ACL登陆认证
前篇文章ACL授权实例介绍了授权,授权完成之后,就要进行认证.ACL的认证主要分为登陆认证与即时认证.所谓登录认证就是在用户登陆的时候,进行信息认证.根据用户Id,加载上来该用户所拥有的权限模块:而即 ...
随机推荐
- Android 高级UI组件(二)
1.ExpandableListView 显示垂直滚动两级列表的条目,只允许两个层次 整体思路: 要给ExpandableListView设置适配器,那么必须先设置数据源. 数据源,就是此处的适配器类 ...
- 【Service】【Database】【Oracle】Oracle client 12.1.0.2 for MacOS
1. 概述:为了在我的macos上搭建python的cx_Oracle开发环境,首先需要配置oracle client 2. 环境与版本: 2.1. OS:Mac OS Sierra 10.12.2 ...
- Java 设计模式--策略模式,枚举+工厂方法实现
如果项目中的一个页面跳转功能存在10个以上的if else判断,想要做一下整改 一.什么是策略模式 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决 ...
- maven常用命令(待补充)
1.mvn clean 删除已经编译好的信息 2.mvn compile 编译src/main/java目录下的.java文件 3.mvn test 编译src/main/java和src/test/ ...
- 深度学习初探——符号式编程、框架、TensorFlow
一.命令式编程(imperative)和符号式编程(symblic) 命令式: import numpy as np a = np.ones(10) b = np.ones(10) * 2 c = b ...
- Windows下mysql5.6升级到5.7的方法(亲测有效哦!)
Mysql的升级方式分为两种:原地升级和逻辑升级.这两种升级方式,本质没有什么区别的. 只是在对数据文件的处理上有些区别而已.原地升级是直接将数据文件进行拷贝,而逻辑升级对数据文件的处理方式是通过逻辑 ...
- Mac 下安装Phonegap开发环境
Mac 下安装Phonegap开发环境 2014.09.11 星期四 评论 0 条 阅读 5,613 次 作者:野草 标签:phonegap ios mac 什么是Phonegap呢?Phon ...
- [BUUCFT]PWN——pwn2_sctf_2016
pwn2_sctf_2016[整数溢出+泄露libc] 题目附件 步骤: 例行检查,32位,开启了nx保护 试运行一下程序,看看大概的执行情况 32位ida载入,shift+f12检索程序里的字符串, ...
- 深刨显式锁ReentrantLock原理及其与内置锁的区别,以及读写锁ReentrantReadWriteLock使用场景
13.显示锁 在Java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.Java5.0增加了一种新的机制:ReentrantLock.与之前提到过的机 ...
- MySQL 的日志:binlog
前言:binlog 用于记录数据库执行写入性操作的日志信息,以二进制的形式保留在磁盘中.它是由 Server 层进行记录的,使用任何存储引擎都会产生 binlog. 实验准备 我们通过 Docker ...

