SpringSecurity源码解析(一)

这里用的是springsecurity默认的表单提交方式

下面这张图片是采用默认的表单提交方式的一个拦截器的链。
SpringSecurity源码解析(一)_第1张图片

  1. 首先是经过的第一个类UsernamePasswordAuthenticationFilter(前面的我就不说了,第二个是一个基于请求头处理的拦截器、第3个是退出登录的拦截器。前两个我也没有细细研究),但是呢,他继承了AbstractAuthenticationProcessingFilter 这个抽象类中,所以要先执行父类中的的 doFilter这个方法,实际上来说这个就是spring里面实现拦截器的一个类。
  2. SpringSecurity源码解析(一)_第2张图片
    重点看这个地方。这个地方实现的就是我们进行认证的方法逻辑代码。
    打断点就去就看到了我们实现认证的逻辑代码。
    SpringSecurity源码解析(一)_第3张图片

2.1 首先先从request请求中拿到username和password密码,然后生成一个对象UsernamePasswordAuthenticationToken 相当于是一个临时存储用户名和密码的地方。
SpringSecurity源码解析(一)_第4张图片
2.2 然后就进入到这个this.getAuthenticationManager().authenticate(authRequest) 这个方法里面。首先我们要想到这个地方我们是要做什么,对不,因为上一步已经拿到了前端传过来的参数了并且已经把他封装了起来,这里不就是轮到解析了嘛。这里用到的解析是AuthenticationManager,这是一个接口,而他默认的实现类是ProviderManager这个实现类。就是用来处理认证UsernamePasswordAuthenticationToken 这个对象的。
首先和大家说一点。他这里的处理这个对象Authentication的处理类有很多。如何判断是哪个类去处理UsernamePasswordAuthentication呢,

下面的是一个处理类的公共接口的一个说明
SpringSecurity源码解析(一)_第5张图片
那么我们来看一下他的默认实现类DaoAuthenticationProvider,如果大家看到这个类,可能会发现,在这个类里面我们并没有找到这个supports.这个方法,也没有找到他实现的认证的方法。而且他实现的并不是AuthenticationProvider这个接口,而是继承了一个叫AbstractUserDetailsAuthenticationProvider这个类,那么我们就到这个类里面看一下。咦,找到这个方法了,
SpringSecurity源码解析(一)_第6张图片
就是这里,说明这个认证处理器是用来处理UsernamePasswordAuthenticationToken这个类的。所以我们用到的处理器,是这个AbstractUserDetailsAuthenticationProvider类的实现类。DaoAuthenticationProvider。所以我们再接着上面看。进入到下面得图得方法。
SpringSecurity源码解析(一)_第7张图片

  1. 此时我们进入到AbstractUserDetailsAuthenticationProvider中的authenticate方法。因为DaoAuthenticationProvider这个处理器是实现的AbstractUserDetailsAuthenticationProvider,所以才会先进入到AbstractUserDetailsAuthenticationProvider,而不是DaoAuthenticationProvider,但是这里调用的类是默认实现类DaoAuthenticationProvider。
    下面是调用AbstractUserDetailsAuthenticationProvider的authenticate方法。(下面图片中authentication写错了,应该是返回的一个UserDetails)
    SpringSecurity源码解析(一)_第8张图片
    这个地方就是DaoAuthenticationProvider的retrieveUser。可以这么认为,这个方法就是拿到在数据库中的当前该用户名的信息。
    SpringSecurity源码解析(一)_第9张图片
    而具体的实现类。就是我们在使用这个框架的时候必须实现的一个接口。UserDetailsService。这个接口
    SpringSecurity源码解析(一)_第10张图片

  2. 走完retrieveUser这个方法后,就进入到additionalAuthenticationChecks这个方法。而这个方法在抽象类AbstractUserDetailsAuthenticationProvider也是没有实现的,而是在实现类中DaoAuthenticationProvider进行实现的。
    SpringSecurity源码解析(一)_第11张图片
    下面就是DaoAuthenticationProvider中的实现方法。
    SpringSecurity源码解析(一)_第12张图片
    然后比对完成后就基本没有什么了。就是在返回结果处,把比对结果是相同的用户进行重新创建,进行存储。
    SpringSecurity源码解析(一)_第13张图片

  3. 我们接着上面中返回结果的那个方法createSuccessAuthentication打断点的看。就是下面的方法。
    SpringSecurity源码解析(一)_第14张图片
    然后在一步步的打断点。就把封装好的Authentication给返回到步骤2中的第一张图里面了。

  4. 这里我们在接着上面的步骤2中的图进行打断点进行查看
    SpringSecurity源码解析(一)_第15张图片
    接着下面的this.sessionStrategy.onAuthentication这个方法,这个方法的目的就是在于,下次请求进来的时候,我们就可以通过sessionid,直接拿到用户信息。完成验证用户。这个方法可以理解为保存用户信息。
    SpringSecurity源码解析(一)_第16张图片

这里我们着重查看successfulAuthentication这个方法。
SpringSecurity源码解析(一)_第17张图片
然后就一步步的进行返回了,基本的认证流程就是这个样子了。

下面就是继续将,在我们登录过来,接下来的请求我们是如何判断他是已经认证过的。可以通过的了。

猜测就是在刚才存session那个地方。存了一个session的标识,然后从已经登录的列表中判断是否存在当前用户,进行判断,明天继续看。

你可能感兴趣的:(java,spring,java)