最近在研究SpringSecurity,肝了好多天,算是有点收获,在这里分享下
SpringSecurity是什么?
SpringSecurity是一个强大的可高度定制的认证和授权框架,对于Spring应用来说它是一套Web安全标准。SpringSecurity注重于为Java应用提供认证和授权功能,像所有的Spring项目一样,它对自定义需求具有强大的扩展性。
要对Web资源进行保护,最好的办法莫过于Filter要想对方法调用进行保护,最好的办法莫过于AOP。
SpringSecurity其核心就是一组过滤器链,在spring security中一种过滤器处理一种认证方式,项目启动后将会自动配置
Spring Security进行认证和鉴权的时候,就是利用的一系列的Filter来进行拦截的。
如图所示,一个请求想要访问到API就会从左到右经过蓝线框里的过滤器,其中绿色部分是负责认证的过滤器,蓝色部分是负责异常处理,橙色部分则是负责授权。经过一系列拦截最终访问到我们的API。这里面我们只需要重点关注两个过滤器即可:UsernamePasswordAuthenticationFilter负责登录认证,FilterSecurityInterceptor负责权限授权。
这里面我们只需要重点关注两个过滤器即可:UsernamePasswordAuthenticationFilter负责登录认证,FilterSecurityInterceptor负责权限授权。
一般Web应用的需要进行认证和授权。
认证(Authentication):验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户
授权(Authorization):经过认证后判断当前用户是否有权限进行某个操作
而认证和授权就是SpringSecurity作为安全框架的核心功能。
说明:Spring Security的核心逻辑全在这一套过滤器中,过滤器里会调用各种组件完成功能,掌握了这些过滤器和组件你就掌握了Spring Security!这个框架的使用方式就是对这些过滤器和组件进行扩展。
认证
登录流程:
- 通过用户输入的用户名和密码去和数据库中的数据进行比对,登录认证成功之后根据用户名和密码通过jwt生成一个token返回给前端(前端每次请求都会携带token到请求里面),同时将token存入redis(其中用户id作为key,用户信息作为value)(主要是为了不让后续的校验流程频繁的查询数据库)
- 这里的UserDetailsService默认是去查内存来认证用户名和密码的,需要自定义UserDetailsService这个接口去查自己的数据库的数据进行认证
校验流程:
- 前端每次发送请求的时候,请求头都会携带token。
- 后端通过jwt解析出用户的id,然后从redis根据key去拿到用户信息
- 通过用户的信息查询用户可以使用的权限,然后返回给前端去访问能访问的资源
前后端进行认证的流程:
整体流程:
其中:
- Authentication接口:它的实现类,表示当前访问系统的用户,封装了用户相关信息。
- AuthenticationManager接口:定义了认证Authentication的方法。
- UserDetailsService接口:加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法。
- UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回。然后将这些信息封装到Authentication对象中。
SpringSecurity的配置类
spring security和spring mvc做了很好的集成,一共只需要做两件事,给web配置类加上@EanbleWebSecurity,继承WebSecurityConfigurerAdapter定义个性化配置。这里我们在加上一个全局的注解@EnableGlobalMethodSecurity(prePostEnabled=true),该注解会在方法执行前进行验证。
- configure(HttpSecurity httpSecurity):用于配置需要拦截的url路径、jwt过滤器及出异常后的处理器;
- configure(AuthenticationManagerBuilder auth):用于配置UserDetailsService及PasswordEncoder;
- UserDetailsService: SpringSecurity定义的核心接口,用于根据用户名获取用户信息,需要自行实现;
- UserDetails:SpringSecurity定义用于封装用户信息的类(主要是用户信息和权限),需要自行实现;
- PasswordEncoder:SpringSecurity定义的用于对密码进行编码及比对的接口,目前使用的是BCryptPasswordEncoder;
- JwtAuthenticationTokenFilter:在用户名和密码校验前添加的过滤器,如果有jwt的token,会自行根据token信息进行登录。
与SpringSecurity相关的原理大致就这么多,解下来我写具体的使用步骤
参考:
Spring Boot Security - 废物大师兄 - 博客园 (cnblogs.com)
@PreAuthorize 权限控制的原理 - 简书
整合SpringSecurity和JWT实现登录认证和授权_jwtauthenticationtokenfilter_Java升级之路的博客-CSDN博客