述
前文中,简单的使用了一下Spring Security,做了基本的用户名密码的认证,下面来大致的看一下,登录这个过程,Spring Security做了哪些事情
基本原理
Spring Security的认证授权等处理是经过一系列的filter实现的,大致流程图如下:
一个请求进来,先是经过一系列的security的过滤器链
UsernamePasswordAuthenticationFilter
从图上来看,第一个进入的filter是 UsernamePasswordAuthenticationFilter
, 就是用户名密码认证, 图中,这个下面是一个 BasicAuthenticationFilter
, 这两个是只走一个的,一个是表单的认证,一个是basic的认证, 通常情况我们都是通过用户名密码去做认证的, 所以这里只看 UsernamePasswordAuthenticationFilter
, 部分源码如下:
这一步主要就是从请求中获取了用户名和密码,然后生成一个token,就是 UsernamePasswordAuthenticationToken
对象, 看一下他的构造
然后这里下一步 return 的这一步,这里获取了一个 AuthenticationManager
,这是一个接口,他有很多的实现,这里是用的是 ProviderManager
,点进去看一下具体调用的方法
这一层主要是判断一下,传进来的这个token是不是支持, 我们传过去的是一个 UsernamePasswordAuthenticationToken
, 还可以能有其他的登录方式,比如是第三方登录等
然后进到这个实际处理认证的方法中看一下,代码如下:
前面这部分就是个简单的 去从缓存里面找用户
然后是下面部分的代码:
这里才是用户名密码的检查,最终会返回一个认证之后的 Authentication
对象
这个方法才是主要的认证方法,总结一下主要干了这几件事:
- 去调用自己实现的UserDetailsService,返回UserDetails,就是源码里面的
retrieveUser(...)
这个方法 - 然后是做了两次用户检查, 一次是预检查主要是帐号是否被冻结,是否过期等
- 第二次检查是密码的验证,这里会调用
PasswordEncoder
,具体可以点进去看一下 - 最后又做了一次检查,是检查UserDetails是否可用
- 都检查完了之后,返回经过认证的
Authentication
到这儿 UsernamePasswordAuthenticationFilter
就走完了
FilterSecurityInterceptor
然后再看一下上面那个过滤器链的图, 最后一级是 FilterSecurityInterceptor
, 这个拦截器,他主要的功能就是做一个最终的判断, 比如我们的 UsernamePasswordAuthenticationFilter
通过了,但是没有权限去访问的话,也会被打回去,这个过滤器如果放行了,那请求就到了我们接口了,简单看一下这个类的代码
这里的这个doFilter()
方法,其实就是调到了我们项目里面的controller层了
ExceptionTranslationFilter
最后再来看一下 ExceptionTranslationFilter
这个类,先看一下源码, 关键代码如下:
他其实就是调下一级的filter,然后主要的逻辑都是在catch里面捕获异常, 他就是个最终的异常处理,捕获到 FilterSecurityInterceptor
里面的异常,然后根据不同的异常做出不同的处理, 比如用户名密码不对,就返回一个登录页面等
整个认证的大致流程就是这样,先大概的了解一下, 之后再详细介绍