secruity通过加载很多过滤器来拦截请求,进行身份校验,其中进行密码和用户校验的过滤器是UsernamePasswordAuthenticationFilter,类从请求中获取username和password然后疯转成一个
UsernamePasswordAuthenticationToken对象通过调用
AuthenticationManager接口的实现类
使用providerManager调用
authenticate方法把
UsernamePasswordAuthenticationToken这个作为参数传递
这里通过provider链
providers这个中的
是具体的执行方法返回是一个
Authentication,
具体来说就是先从缓存中根据username拿到userdetails,如果没有就调用
retrieveUser方法进行查找拿到userdetails,方法内容如下
通过
UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);这个方法拿到
这个时候就可以自定义
实现这个接口就可以自定义从数据库中根据name查询user对象封装成一个userdetails,
返回的details要进行验证密码校验是在
retrieveUser方法的到userdetails之后进行check,包括权限检查,密码检查
String presentedPassword = authentication.getCredentials().toString();拿到用户给的password
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { this.logger.debug("Authentication failed: password does not match stored value"); throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); }
进行匹配,匹配到了继续进行其他check
匹配不到抛出异常,有定义的异常处理器处理异常。
最后如果检验都通过返回一个
Authentication然后进行后续操作,把这个当作cookie返回浏览器或者进行用户信息缓存等。
authenticate方法(UsernamePasswordAuthenticationToken这个是
authentication的一个实现类);