SpringSecurity
1、简介
Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。
一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。
记住几个类:
- WebSecurityConfigurerAdapter:自定义策略
- AuthenticationManagerBuilder:自定义策略
- @EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是进行认证和授权(访问控制)。
认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户
授权:经过认证后判断当前用户是否有权限进行某个操作
而认证和授权也是SpringSecurity作为安全框架的核心功能。
2、快速入门
2.1、准备工作
首先要搭建一个简单的SpringBoot工程
1、添加依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
2、创建Controller
@RestController
public class HelloController {@RequestMapping("/hello")public String hello(){return "hello";}
}
3、引入SpringSecurity依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
必须依赖后我们在尝试去访问之前的接口就会自动跳转到一个SpringSecurity的默认登录页面,默认用户名是user,密码会输出在控制台,必须登录之后才能对接口进行访问
3、认证
3.1、登录校验流程
3.2、原理初探
3.2.1、SpringSecurity完整流程
SpringSecurity的原理其实就是一个过滤链,内部包含了提供各种功能的过滤器。
图中只展示了核心过滤器
UsernamePasswordAuthenticationFilter:负责处理我们在登录页面填写了用户名密码后的登录请求
ExceptionTranslationFilter:处理过滤器中抛出的任何AccessDeniedException和AuthenticationException
FilterSecutityInterceptor:负责权限校验的过滤器
3.2.2、认证流程详解
概念:
Authentication接口:它的实现类,表示当前访问系统的用户,封装了用户的相关信息
AuthenticationManager接口:定义了认证Authentication的方法
UserDetailsService接口:加载用户特定数据接口,里面定义了一个根据用户名查询用户信息的方法
UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回,然后将这些信息封装到Authentication对象中
- 登录
- 自定义登录接口
- 调用ProviderManager的方法进行认证,如果认证通过生成jwt
- 把用户信息存入redis中
- 自定义UserDetailsService
- 在这个实现类中去查询数据库
- 自定义登录接口
- 校验
- 定义jwt认证过滤器
- 获取token
- 解析token获取其中的userid
- 从redis中获取用户信息
- 存入SecurityContextHolder中
- 定义jwt认证过滤器
4、授权
4.1、权限系统的作用
例如一个学校图书馆的管理系统,如果是普通学生登录就能看到借书还书相关的功能,不可能让他看到并且去使用添加书籍信息,删除书籍信息等功能。但是如果是一个图书馆管理员的账号登录了,应该就能看到并使用添加书籍信息,删除书籍信息等功能。
总结起来就是不同的用户可以使用不同的功能。这就是权限系统要去实现的效果。
我们不能只依赖前端去判断用户的权限来选择显示哪些菜单哪些按钮。因为如果只是这样,如果有人知道了对应功能的接口地址就可以不通过前端,直接去发送请求来实现相关功能操作。
所以我们还需要在后台进行用户权限的判断,判断当前用户是否有相应的权限,必须具有所需权限才能进行相应的操作。
4.2、授权基本流程
在SpringSecurity中,会使用默认的FilterSecurityInterceptor来进行权限校验。在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。
所以我们在项目中只需要把当前登录用户的权限信息也存入Authentication。
然后设置我们的资源所需要的权限即可。
eptor中会从SecurityContextHolder获取其中的Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。
所以我们在项目中只需要把当前登录用户的权限信息也存入Authentication。
然后设置我们的资源所需要的权限即可。