Spring Security
Spring Security是Spring项目组提供的安全服务框架,核心功能包括认证和授权。它为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。
1.1 认证
认证即系统判断用户的身份是否合法,合法可继续访问,不合法则拒绝访问。常见的用户身份认证方式有:用户名密码登录、二维码登录、手机短信登录、脸部识别认证、指纹认证等方式。认证是为了保护系统的隐私数据与资源,用户的身份合法才能访问该系统的资源。
1.2 授权
授权即认证通过后,根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有权限则拒绝访问。比如在一些视频网站中,普通用户登录后只有观看免费视频的权限,而VIP用户登录后,网站会给该用户提供观看VIP视频的权限。认证是为了保证用户身份的合法性,授权则是为了更细粒度的对隐私数据进行划分,控制不同的用户能够访问不同的资源。
举个例子:认证是公司大门识别你作为员工能进入公司,而授权则是由于你作为公司会计可以进入财务室,查看账目,处理财务数据
二.流程梳理
2.1 登录效验流程

2.2 Security流程
SpringSecurity的原理就是一个过滤器链,内部包含了提供各种功能的过滤器,下图整理出一些主要的过滤器。

SpringSecurity的认证流程

概念速查:
-
Authentication接口:它的实现类,表示当前访问系统的用户,封装了用户相关信息
-
AuthenticationManager接口:定义了认证Authentication的方法
-
UserDetailsService接口:加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法
-
UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回。然后将这些信息封装到Authentication对象中
-
SecurityContextHolder对象:上下对象,其他方法中用用户信息的时候就用这个东西获取。
个人理解:从上面的认证流程中总结,基本就是把入参的用户名密码封装到Authentication对象里,中间通过一系列的骚操作处理,处理成UserDetails对象,然后在把UserDetails对象封装成Authentication对象返回的过程
1:上述流程是Security框架默认的处理流程,数据对比是获取的内存中的,真正的开发中我们要在数据库中获取用户信息做对比,主要处理的就是UserDetailsService实现类里面做对比的内容
2:输入密码和验证通过之后,都会到AbstractAuthenticationProcessingFilter实现类中进行处理,真正开发中不能用他提供的登录页面,并且当登录成功之后我们还有一些其他的操作要做,所以我们要重新搞一个自己的AbstractAuthenticationProcessingFilter实现类
总结而言就是,自己重写头尾两个实现类来搞自己的业务逻辑。
三.快速开始
在pom中引入Security的Starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Tips:引入之后,启动项目会跳到一个他默认的页面,这个页面由security提供,默认的用户名是user密码会在启动的时候控制台输出
四.功能实现
4.1 思路分析

4.1.1 登录
-
自定义登录接口
-
不用UsernamePasswordAuthenticationFilter,自己写一个,用来获表单提交的用户名密码
-
调用AuthenticationManager中的authenticate方法让Filter链走下去
-
认证通过后,使用JWT封装Token,数据存入Redis
-
-
自定义UserDetailsService实现类
-
查库,检查用户名密码是否有效
-
4.1.2 校验
-
定义Jwt认证过滤器
-
获取、解析Token
-
根据Token从Redis中获取用户相关信息
-
存入SecurityContextHolder对象方便其他内容获取用户信息
-
4.1.3 配置类
-
创建一个类,继承WebSecurityConfigurerAdapter
-
注入AuthenticationManager对象(登录接口中会有用到这个对象,所以得注入到容器中)
-
注入密码
-
重写
4.1.4 加密
-
加密方式
-
注入BCryptPasswordEncoder替换默认的PasswordEncoder实现类的加密方式(当然也可以自定义加密方式,只要实现PasswordEncoder并且注入到Spring容器中就行)
-
Tips:Security默认的加密方式是PasswordEncoder:{id}password。他会根据id去判定加密方式,但是一般我们都会改掉,BCryptPasswordEncoder也是Security提供的一种加密方式
4.1.5 退出
-
获取Token,然后删掉Resid中的信息
4.1.6 权限
-
开启权限使用注解
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) -
自定义权限方式
4.2 功能实现
Security配置类
/**
* spring security配置
*
* @author system
*/
//开启权限注解
