Security本质上是一个过滤器链(filterchain),用户访问时,会依次过滤,当它访问到UsernamePasswordAuthenticationFilter
时,security会将用户名和密码封装到Authentication对象中,并将对象传递给AuthenticationManager对象,
调用Authentica方法进行认证,这个方法会调用DaoAuthenticationProvider对象的authticate方法,
authticate方法会调用InMemoryUserDetailsManager对象的loadUserByUsername方法在内存中查找,
我们需要在这里将查找地方改为数据库查找,查找出来后将数据封装成UserDetails对象,并返回给DaoAuthenticationProvider对象的authticate,
然后通过PasswordEncoder对比UserDtails中的密码是否正确,如果正确就把UserDetails中的权限信息设置到Authentication对象中,并返回Authentication对象,
最后UsernamePasswordAuthenticationFilter会判断是否返回了Authentication对象,如果返回了就使用SecurityHolder.getContext().setAuthentication方法存储该对象,
其他过滤器中会通过SecurityContextHolder来获取当前用户信息
登录时在token中包含一个随机数,并把随机数同时存入redis中。可验证同一时间重复登录