Spring Security 总体结构概览

Spring Security 概览

Spring Security的功能能够归纳为两部分,即认证和受权。html

认证就是一个用户使用令牌(最多见的是帐号和密码)登录,服务器验证这个用户的令牌是否有效。html5

受权则是认证以后,系统根据这个用户的信息判断他拥有哪些权限,能访问哪一种资源,能对资源进何种操做,并向他授予相关的权限,对没有权限访问的用户进行阻止。java

这里说的Spring Security是基于Servlet容器的。web

从Filter提及

Spring Security的Servlet支持是基于Servlet的Filter的。Filter能够对请求进行处理,但Filter通常会将处理好的请求交给FilterChain中的下一个Filter,即一个个Filter按照相应的顺序组合起来造成了一个Filter链,从而达到对请求进行过滤/提早处理的效果。spring

FilterChain

当请求到达时,Servlet容器会初始化一个FilterChain,并将请求传递到里面进行处理:api

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    // do something before the rest of the application
    chain.doFilter(request, response); // invoke the rest of the application
    // do something after the rest of the application
}
复制代码

通过一个个Filter处理后请求才到达Servlet处理并响应,因而可知,Filter在FilterChain中组织的顺序很是重要。安全

DelegatingFilterProxy

由于Servlet容器跟Spring的IoC容器是两种不一样的容器,Servlet容器没法获知Spring容器中各类Bean(用户自定义Filter)的信息,也没法直接使用这些Bean(Filter),因此须要在二者间创建桥梁,使得咱们定义的Bean(Filter)可以被Servlet容器使用。服务器

Spring提供了一种叫DelegatingFilterProxy的Filter实现。app

DelegatingFilterProxy

它像普通的Filter同样被插入到FilterChain中,它的功能是将请求委托给Spring容器里的Bean Filter来处理,从而创建起Servlet容器和Spring容器之间的桥梁。性能

例如图中DelegatingFilterProxy会在Spring容器中寻找Bean Filter0,并将ServletRequestServletResponse传递过去:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    // Lazily get Filter that was registered as a Spring Bean
    // For the example in DelegatingFilterProxy delegate is an instance of Bean Filter0
    Filter delegate = getFilterBean(someBeanName);
    // delegate work to the Spring Bean
    delegate.doFilter(request, response);
}
复制代码

DelegatingFilterProxy的另外一个好处是它能够延迟加载Bean Filter实例,由于FilterChain会在Servlet容器启动前初始化,这样能够提高Servlet容器启动的性能。

FilterChainProxy

上面提到DelegatingFilterProxy会将请求委托给Bean Filter,而其实这里的Bean Filter也不会直接处理请求,会将请求进一步转发,这个Bean Filter便是FilterChainProxy

FilterChainProxy是Spring Security提供的特殊Filter,它会将请求委托到另外一种FilterChain中,即Spring的FilterChain:SecurityFilterChain

SecurityFilterChain

咱们能够很天然地想到,SecurityFilterChain中即是Spring的Bean Filter了,即SecurityFilter

SecurityFilter

这里的SecurityFilter就是普通的Bean,他们能够识别本身能处理的请求并对请求处理,不然将请求传给链中的下一个Filter,例如最多见的UsernamePasswordAuthenticationFilter能够识别处理基于表单的登录请求。

值得注意的是,SecurityFilterChain能够有多条,能够根据不一样的请求来判断请求应该被传递到哪一个SecurityFilterChain中:

好比符合/api/**匹配模式的URL应该被传递到最上面的SecurityFilterChain中,这个请求一旦匹配到了某个上游的SecurityFilterChain,下游的SecurityFilterChain就不会再进行匹配。

Many SecurityFilterChains

有哪些Security Filter?

官方文档给出了按照Spring Security Filter排列顺序的列表:

Security Filters

处理安全异常

ExceptionTranslationFilter容许将AccessDeniedExceptionAuthenticationException异常转换为HTTP响应,从它的名字能够看到,它也是一个Filter,能够被插入到SecurityFilterChain中,这是它的工做流程:

ExceptionTanslationFilter

  1. 它调用下层的Filter处理请求
  2. 若是下层Filter抛出AuthenticationException,则会被它捕获(见下面代码),并调用它的startAuthentication()方法跳转进行认证。(图中的SecurityContextHolder等几个东西属于认证功能部分,能够先不用管)
  3. 若是下层Filter抛出AccessDeniedException则对异常做出响应,通知用户禁止访问。

总结

从上面能够看到,Spring Security的功能是经过Filter来实现的。每一个Filter都是一个Bean,用户经过配置不一样的Filter或自行实现Filter来达到保护应用/认证/受权等目的,不一样的Filter组成了多个FilterChain,来实现不一样的要求。

参考资料:Spring Security Reference - Version 5.3.2.RELEASE

相关文章
相关标签/搜索