Spring Security的AuthenticationManager的authenticate()如何校验用户名密码正确性?
认证校验逻辑工作原理
这个校验逻辑能正常运行,核心是Spring Security的AuthenticationManager内部已经自动完成了用户信息查询和密码比对的流程,你在Controller里看到的执行顺序只是你自己编写的业务代码的顺序,并不代表Spring Security内部的调用顺序。
具体的内部执行流程如下:
- 你注入的
AuthenticationManager默认实现是ProviderManager,它会匹配到处理用户名密码认证的DaoAuthenticationProvider来处理本次认证请求 DaoAuthenticationProvider拿到你传入的UsernamePasswordAuthenticationToken后,第一步就会调用你配置的CustomUserDetailsService的loadUserByUsername方法(注意这是Spring Security规定的标准接口方法,不是你后面自定义的loadCompleteUserByUsername),根据用户名调用GET-USER-WS接口拉取对应用户的存储信息(包括加密后的密码、账号状态等核心认证字段)- 拿到用户存储信息后,
DaoAuthenticationProvider会用你项目中配置的PasswordEncoder,把请求传入的明文密码加密后,和存储的加密密码做比对:- 如果密码不匹配,直接抛出
BadCredentialsException,也就是你捕获的凭证错误 - 如果查询到的用户账号状态是禁用的,抛出
DisabledException - 密码比对通过、账号状态正常的话,认证就通过,不会抛出异常
- 如果密码不匹配,直接抛出
- 你在Controller里认证通过后调用的
loadCompleteUserByUsername是你自定义的扩展方法,目的是拿到更多用户业务字段来生成JWT的payload内容,和认证过程里调用的loadUserByUsername是两个独立的方法,所以才会出现在认证逻辑之后执行的情况。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

