一.原理
1.Spring Security认证基于过滤器实现,是一条过滤链。
为什么基于过滤器实现:
从可控性来说的话,过滤器是servlet层面的,拦截器是spring层面的。
也就是说,既然要做权限控制,最好就是从请求入口开始处理,也就是servlet层面,而不应该放在所有的过滤器后面再处理,某些请求很可能因为被过滤器处理掉了导致后续拦截器无法处理。
二.认证流程
1.用户提交用户名/密码,来到UsernamePasswordAuthenticationFilter这个过滤器
2.UsernamePasswordAuthenticationFilter调用attemptAuthentication()这个方法,但这个方法会让UsernamePasswordAuthenticationToken调用unauthenticated()这个方法,最后将请求信息封装到Authentication(里面装的是用户提交的用户名/密码)
3.接着又去执行认证authenticate()这个方法委托给AuthenticationManager,AuthenticationManager又会委托认证authenticate()给合适的Provider实现类(具体取决于你的实现方式,内存用户,redis,jdbc)
4.provider实现类自己无法完成这项校验工作,找来了UserDetailsService来帮忙,UserDetailsService会执行loadUserByUsername()这个方法,返回正确的UserDetails
5.Provider实现类会通过PasswordEncoder对比UserDetails中的密码与我们前面封装的这个Authentication对象中的密码是否一致,接着去填充原来这个Authentication对象,把一些没有的数据填充进去,最后返回给我们的UsernamePasswordAuthenticationFilter这个过滤器
6.UsernamePasswordAuthenticationFilter这个过滤器会通过SecurityContextHolder的getContext()方法拿取上下文,SecurityContext实现类会将最后过滤器所接收到的这个Authentication对象保存到我们的上下文