一、什么是spring security?
1、分为用户认证(Authentication)和用户授权(Authorization)两个部分.
用户认证指的是验证某个用户是否为系统中的合法主体,
也就是说用户能否访问该系统。
用户授权指的是验证某个用户是否有权限执行某个操作。
2、 框架简介
要对Web资源进行保护,最好的办法莫过于Filter
要想对方法调用进行保护,最好的办法莫过于AOP。
springSecurity进行认证和鉴权的时候,就是利用的一系列的Filter来进行拦截的。
请求经过fifter链:
(1)、SecurityContextPersistenceFilter(获取设置上下文):
获取SecurityContext(安全上下文),
并将上下文设置到SecurityContextHolder。
(2)、UsernamePasswordAuthenticationFilter(认证):
处理来自表单提交的认证,通过用户名和密码,生成认证令牌,
然后通过authenticManage来进行认证。
成功或失败后执行AuthenticationSuccessHandler
和 AuthenticationFailureHandler接口实现类中的自定义逻辑。
(3)、FilterSecurityInterceptor(授权):
对request进行权限判断,允许访问或者抛出accessDenied异常。
也就是授权。
3、框架的核心组件
(1)、SecurityContextHolder:
提供对SecurityContext(安全上下文,认证信息就存在此处)的访问。
(2)、SecurityContext:
持有Authentication对象和其他可能需要的信息。
(3)、AuthenticationManager
认证器接口,里面包含多个不同类型的AuthenticationProvider,
通过Authentication令牌的类型来决定调用哪个Provider来执行
认证处理。
(4)、 AuthenticationProvider
主要用来进行认证操作的类 调用其中的authenticate()方法去
进行认证操作。
(5)、Authentication:
Spring Security方式的认证主体。
(6)、GrantedAuthority:
含当前用户的权限信息,通常使用角色表示。
(7)、UserDetails:
构建Authentication对象必须的信息,可以自定义,
可能需要访问DB得到。
(8)、UserDetailsService:
通过username构建UserDetails对象,
通过loadUserByUsername根据userName获取UserDetail对象。
- 工作流程是怎样的?
5、基础概念总结:
(1)、spring security分为认证和鉴权两个方面,认证就是根据参数去查询数据库,
有没有此用户存在。鉴权就是通过用户/角色/权限表以及两张中间表
(用户角色表/角色权限表),联查查出该用户拥有的访问权限是那些。
(2)、spring security认证和鉴权,实际上就是由一个fifter链组完成的
<1>、经过SecurityContextPersistenceFilter
生成一个安全上下文(SecurityContext)。
<2>、经过UsernamePasswordAuthenticationFilter,
生成一个令牌(AuthenticationToken),
将这个令牌传入到AuthenticationManage(认证器)。
<3>、AuthenticationManage是一个代理接口,
里面包含了一系列的AuthenticationProvider 。
<4>、通过传入的AuthenticationToken调用不同的
AuthenticationProvider中的方法进行认证,
比如DaoAuthenticationProvider,
通过重写authenticate方法进行自定义的认证。
<5>、DaoAuthenticationProvider 在进行认证的时候需要一个
UserDetailsService 来获取用户的信息 UserDetails,
将UserDetails传入UsernamePasswordAuthenticationToken
生成一个Authentication。
<6>、认证成功调用AuthenticationSuccessHandler实现类方法,
认证失败调用AuthenticationFailureHandler。
<7>、以上认证阶段结束。
<8>、鉴权是经过FilterSecurityInterceptor进行的,
通过传来的认证主体(Authentication),
可以得到UserDetails信息中的权限信息,
然后和requst中的url进行比对,包含有的就可以访问restApi。
6、总结
(1)、认证流程开始,首先通过SecurityContextPersistenceFilter
生成一个SecurityContext(安全上下文),
之后的fifter之间的信息传递全靠这个来实现。
(2)、前台传来的userName和password,
通过UsernamePasswordAuthenticationFilter,
生成一个令牌(AuthenticationToken)
(3)、按照令牌(AuthenticationToken)类型的不同,
调用不同的接口实现类中的认证方法,
比如令牌类型是读数据库类型,
就调用程序员自己写的DaoAuthenticationProvider
接口实现类中的authenticate方法进行认证。
(4)、 DaoAuthenticationProvider 在进行认证的时候需要一个
UserDetailsService 来获取用户的信息 UserDetails,
这个UserDetailsService由程序员自己实现,
从数据库查出用户信息,封装成UserDetails对象返回即可。
(5)、 将UserDetails传入UsernamePasswordAuthenticationToken方法,
生成一个Authentication。
(6)、Authentication和通过前台传来的
userName和password生成的Authentication
如果认证成功调用AuthenticationSuccessHandler实现类方法,
如果认证失败调用AuthenticationFailureHandler实现类方法。
(7)、以上认证阶段结束,开始授权阶段,
通过FilterSecurityInterceptor过滤器来比对:
Authentication(通过数据库查询出来的认证信息)里面的权限列表
和requst中的url
如果匹配得到,那可以通过,否则就不能访问。