通过测试认证和授权两个功能,我们了解了SpringSecurity的基本使用方法,以及下面的工作流程。
Spring Security解决的问题是安全访问控制,安全访问控制功能实际上是拦截所有进入系统的请求,以检查每个请求是否可以访问其预期的资源。通过Filter或AOP等技术,可以学习前面的知识,Spring Security对Web资源的保护是通过Filter实现的,所以从这个Filter入手,逐步深入Spring Security原理。
初始化Spring 当Security被创建时,它将创建一个名称SpringSecurityFilterChainServlet过滤器的类型是org.springframework.security.web.FilterChainProxy,它实现了javax.servlet.Filter,所以外部请求会经过这样的事情,下图是Spring Security过滤器链结构图:
FilterchainProxy是一个代理,真正起作用的是FilterchainProxy中SecurityFilterchain包含的所有Filter,而这些Filter作为Beran被Spring管理,它们是Spring Security的核心,各有各的职责,但他们不直接处理用户认证,不直接处理用户授权,而是交给认证管理器(AuthenticationManager)和决策管理器(AccessDecisionManager)进行处理。
spring Security功能的实现主要由一系列过滤器链相互配合完成。
介绍了过滤器链中的几个主要过滤器及其功能:
SecurityContextPersistenceFilter 这个Filter是整个拦截过程的入口和出口(即第一个和最后一个拦截器),在请求开始时会从配置开始 SecurityContextRepository 中获取 SecurityContext,然后将其设置为Securitycontextholder。请求完成后 SecurityContextHolder 持有的 SecurityContext 将其保存到配置好的Securitycontextrepository中,同时清除 securityContextHolder 所持有的 SecurityContext;
UsernamePasswordAuthenticationFilter 用于处理表格提交的认证。表格必须提供相应的用户名和密码,并在登录成功或失败后进行处理 AuthenticationSuccessHandler 可根据需要对Authenticationfailurehandler进行相关变更;
FilterSecurityInterceptor 用于保护web资源,使用AccesdecisionManager授权访问当前用户,已详细介绍;
ExceptionTranslationFilter 能够捕捉到来自 FilterChain 所有异常,并进行处理。但它只处理两种异常:AuthenticationException 还有Accesdeniedexception,其他异常将继续抛出。
Spring Security的执行流程如下:
1.用户提交的用户名和密码是通过SecurityFilterchain中的UsernamepaswordAuthenticationFilter过滤器获得的,包装为要求Authentication,通常是UsernamepaswordAuthenticationtiontiontiontion。
2.然后过滤器将Authentication提交给认证管理器(AuthenticationManager)进行认证
3.认证成功后,AuthenticationManager身份管理器返回Authentication实例(包括上述权限信息、身份信息、细节信息,但密码通常被删除)。
4.Securitycontextholder安全上下文容器通过Securitycontextholder填充信息的Authentication第三步.getContext().setAuthentication(…)方法,设置在其中。 由此可见,Authenticaticationmanager接口(认证管理器)是认证相关的核心接口,也是发起认证的起点,其实现类别为Providermanager。而Spring Security支持多种认证方法,所以ProviderManager维护一个List列表,存储多种认证方法,最终的实际认证工作由AuthenticationProvider完成。我们知道web表单对应的AuthenticationProvider实现类为DaoAuthenticationProvider,其内部维护一个Userdetailsservice,负责Userdetails的获取。最后,AuthenticationProvider将UserDetails填充到Authentication