1. spring-security原理大致如下

spring-security入门7---浅析spring-security原理_spring-security
对上图进行说明如下。

1.1 继承了WebSecurityConfigurerAdapter的配置类(以下简称“配置类”)

配置类主要有两个作用

  • 决定了进行用户信息认证与授权究竟走哪条路线;
  • 决定了在具体的路线上到底该怎么走。

举例来讲:

  • 走哪条路线

当我们配置的认证方式为 http.formLogin()… 时,用户在访问我们的项目时会利用上篇博客中讲的表单登陆的方式进行认证,所用的FilterA为 AbstractAuthenticationProcessingFilter ;而如若我们的配置的为 http.httpBasic()… 时,认证的方式为basic认证方式,所使用的FilterA为 BasicAuthenticationFilter

  • 该怎么走

配置类中不仅可以指定哪些方法可以不被校验,而且还可以指定校验成功、校验失败的逻辑,如果需要认证应该在什么样的页面进行认证等等

1.2 FilterA1,A2…

1.2.1 FilterA,A2…的结构大致如下:

①不需要认证的直接放行
②需要认证的逻辑大致如下:
try{
	进行认证
}catch(Exception e){
	//走到这里说明认证失败
	走认证失败后的逻辑,比如重定向到登陆页面或返回一个与认证失败相关的json字符串
}
//走到这里说明已经认证成功
走认证成功后的逻辑,比如重定向到认证之前的请求或返回一个与认证成功相关的json字符串

上篇文章中分析过AbstractAuthenticationProcessingFilter,有兴趣的可以看一下BasicAuthenticationFilter的代码,两者框架基本一致。

1.2.2 认证成功\失败后的逻辑以及如何保证session在多个请求之间进行共享

认证成功和认证失败后的逻辑我们可以通过实现AuthenticationSuccessHandlerAuthenticationFailureHandler接口并重写其抽象方法来进行指定,可参照前面的文章spring-security入门4—自定义登录成功和登录失败的行为.那它们是如何保证session在多个请求之间进行共享的呢.

这里所谓的session在多个请求之间的共享,主要指的是一次认证成功后,其他请求为何不需要再次进行认证的原因.

当认证成功后

如果走我们自己定义的认证成功逻辑让其直接返回一个与认证成功相关的json字符串,那在结果返回浏览器之前势必会先穿过SecurityContextPersistenceFilter(请求返回时穿过)

即使利用spring-security自定义的认证逻辑—>认证成功后跳转到引发认证的请求上。在请求跳转之前,认证成功所在的请求仍要先穿过SecurityContextPersistenceFilter(请求返回时穿过)

上篇文章已经讲过,SecurityContextPersistenceFilter会在请求返回时校验SecurityContextHolder中是否有securityContext,有则放入session;当下次请求过来时,首先也要穿过SecurityContextPersistenceFilter, 此时它将先拿着请求中cookie里的sessionId检查session,如果session中有此sessionId对应的SecurityContext(可以理解为已经认证了的用户)则拿出来放到线程里即SecurityContextHolder中,因此在新的请求中可以通过拿到的SecurityContext来避免进行再一次的认证校验.

保证session在多个请求之间进行共享的逻辑主要在于SecurityContextPersistenceFilter.用图表达如下:

  • 认证成功后直接返回一个与认证成功相关的json字符串时

spring-security入门7---浅析spring-security原理_spring-security_02

  • 认证成功后跳转到引发认证的请求上时

spring-security入门7---浅析spring-security原理_spring-security_03

1.3 FilterB1,B2…

FilterB1,B2我现在还不是很了解,之后懂得多了再细讲。
现在知道的一个属于此类的Filter为RememberMeAuthenticationFilter,该Filter的作用主要是用来完成记住我的功能,接下来的博客应该会有所涉及,这里不再过多赘述。

1.4 ExceptionTranslationFilter和FilterSecurityInterceptor

FilterSecurityInterceptor是访问我们项目API的最后一道屏障,它会按照 配置类 里的配置信息去检查我们的访问请求是否都符合相应的 认证和授权标准 了。如果都符合了,那请求就可以访问到我们的API了;如果不符合,它就会抛出异常,而ExceptionTranslationFilter会捕捉所有这些异常,并按照配置类中的有关配置将请求引导到相应的页面,比如说如果配置了认证方式为 http.formLogin()… 时,当检测到我们没有进行认证时,会按照我们配置的登陆页面进入到我们的表单登陆页。

2 结尾语

通过上面的讲解,已经基本可以把我前面几篇文章都给串起来了。

但是

本篇博客是我看了好几天源码+一些学习视频总结而来,可能有一些不是很对,但对我串联前面几篇文章确实起到了很大的作用,如果文章中有不对的地方,欢迎大家给我指出来!

另外博客中的图片都可以在我的github中找到https://github.com/nieandsun/security