一、工作原理
Spring Security所解决的问题是安全访问控制,而安全访问控制功能就是对所有访问系统的请求进行拦截,校验每个请求是否能访问它所期望的资源。一般可以通过Filter和AOP来实现,Spring Security对web资源的保护是通过Filter来实现的,所以从Filter来入手学习Spring Security的原理。
当初始化Spring Security的时候,会创建SpringSecurityFilterChain的过滤器,类型为org.springframework.security.web.FilterChainProxy,它实现了javax.servlet.Filter。因此外部的请求会经过此类。下图是Spring Security的过滤器链结构图:
pom依赖,单独使用Spring Security只需要添加spring-boot-starter-security它是是spring-security的starter。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
过滤器链的类图:
最终通过AccessDecisionManager和AuthenticationManager进行授权和认证。
1.1 主要过滤器的作用
二 认证流程
2.1 UsernamePasswordAuthenticationFilter
1.找到UsernamePasswordAuthenticationFilter用于账号密码验证
2.继承AbstractAuthenticationProcessingFilter,查看doFilter
3.调用了attemptAuthentication(request, response),这个方法在AbstractAuthenticationProcessingFilter是一个抽象方法
4.实际执行的是UsernamePasswordAuthenticationFilter的attemptAuthentication。
5.后面又调用AuthenticationManager的authenticate(Authentication authentication),这是一个接口,看看实现类
6.认证就是从ProviderManager的authenticate开始,ProviderManager维护了一个 AuthenticationProvider的列表,可以自定义类实现AuthenticationProvider从而进行自己的账号密码验证逻辑。当然Spring Security给我们提供了默认的实现DaoAuthenticationProvider
private List<AuthenticationProvider> providers = Collections.emptyList()
7.遍历providers 调用的authenticate(Authentication authentication)在AbstractUserDetailsAuthenticationProvider里面
8.DaoAuthenticationProvider的retrieveUser方法中调用UserDetailsService查询用户信息
9.获取到用户信息之后调用additionalAuthenticationChecks进行密码校验
10.DaoAuthenticationProvider中的additionalAuthenticationChecks的实现方法进行最终校验
回到doFilter方法,进入successfulAuthentication(request, response, chain, authenticationResult);
将认证结果放入安全上下文