- 认证
- 动态配置接口白名单
- csrf
- BCrypt
是什么
SpringSecurity是基于Spring的安全管理框架,对系统提供认证、权限控制、安全防护的功能。
- 认证 用户是否是系统的合法用户
- 权限控制 用户是否有权限访问系统的资源
Demo
1 | <dependency> |
引入依赖后再次访问接口会跳转到默认的登录页面:

这是因为Security默认使用的basic认证,在前后端分离的环境下,这样肯定是不行的,我们要给前端返回json响应,由前端来处理页面。但是像在给swagger文档加密的时候可以使用这种简单的处理方式
后面创建配置类继承重写WebSecurityConfigurerAdapter的configure方法就不会走basic认证了。
认证流程
SpringSecurity的原理是基于过滤器链来实现的,在这个过滤器链中有一个Authentication对象,过滤器会对这个Authentication对象认证,最后方的过滤器FilterSecurityInterceptor会检查对象有没有认证,如果认证通过则访问API,没有通过抛出异常,交给ExceptionFilter异常过滤器来处理。(Authentication对象有一个isAuthenticated,认证通过后是true)
- 绿色部分负责认证
- 蓝色部分负责处理异常
- 橙色部分负责授权
Security默认提供的认证过滤器UsernameFilter和BasicFilter是基于form表单和basic的,不适用于前后端分离的场景,前后端分离一般使用Token令牌进行认证,因此需要自定义Token令牌过滤器加入到Security的过滤器链条中
核心组件
在编写代码之前,需要先了解下Security的核心组件:
Authentication:认证接口,定义了认证对象的数据形式。
- UsernamePasswordAuthenticationToken是Authentication的实现类,基于用户名和密码认证的
AuthenticationManager:用于校验Authentication
对象,返回一个认证完成后的Authentication
对象。
- AuthenticationManager只是一个接口,它的实现类是ProviderManger,ProviderManager维护了很多个Provider,由这些Provider去完成校验,具体使用哪个Provider,取决于Provider的supports()方法
- 比如UsernamePasswordAuthenticationToken,那么由AbstractUserDetailsAuthenticationProvider去认证,AbstractUserDetailsAuthenticationProvider会去调用UserDetailsService,获取到UserDetails用户信息, 然后再去匹配密码,没问题的话就返回Authenticaion,认证成功
SecurityContext:上下文对象,存放Authentication
对象,提供了get/set方法
SecurityContextHolder:用于拿到上下文对象的静态工具类。
UserDetails:定义了用户的数据形式,也就是数据库中的用户信息,用户名、密码、手机号、用户类型等等
UserDetailsService:去数据库/缓存查询用户,当AuthenticationManager认证用户的时候会调用UserDetailsService的方法
UsernamePasswordAuthenticationToken是基于用户名和密码认证的,而我们实际的认证场景还有短信登录、手机号登录、微信登录等等,可以针对每一种场景去定义一个Token和一个Provider(因为Provider是校验Token的,Token自定义了,Provider肯定也要自定义),然后在Provider来实现认证的逻辑即可。这样其实也是将认证这块代码解耦合了。
开发
配置类
1 |
|