springSecurity登录验证分析——AbstractUserDetailsAuthenticationProvider
来源:互联网 发布:孕妇奶粉 知乎 编辑:程序博客网 时间:2024/05/17 05:10
AbstractUserDetailsAuthenticationProvider类位于org.springframework.security.authentication.dao包下,在
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter中被调用,
该类的public Authentication authenticate(Authentication authentication) throws AuthenticationException方法百常重要,通过这段代码能详细了解整个验证的过程,下面对该方法的代码分段进行说明:
(1) Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports",
"Only UsernamePasswordAuthenticationToken is supported"));
//要求传入的authentication对象必须是UsernamePasswordAuthenticationToken类或其子类的实例
(2)
String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName();
//从authentication中取出登录名
(3) boolean cacheWasUsed = true;
UserDetails user = this.userCache.getUserFromCache(username);
//默认情况下从缓存中(UserCache接口实现)取出用户信息
(4)
if (user == null) {
//如果从内存中取不到用户,则设置cacheWasUsed 为false,供后面使用
cacheWasUsed = false;
try {
//retrieveUser是抽象方法,通过子类来实现获取用户的信息,以UserDetails接口形式返回
user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
} catch (UsernameNotFoundException notFound) {
logger.debug("User '" + username + "' not found");
if (hideUserNotFoundExceptions) {
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
} else {
throw notFound;
}
}
Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
}
(5)
try {
//preAuthenticationChecks和additionalAuthenticationChecks这是UserDetailsChecker接口的实现类
//验证帐号是否锁定\是否禁用\帐号是否到期
preAuthenticationChecks.check(user);
//由子类来完成更进一步的验证
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
} catch (AuthenticationException exception) {
//下面这段代码体现了老外的细腻之处,意思是说如果在调用某个UserDetailsChecker接口的实现类验证失败后,就判断下用户信息是否从内存中得到,如果之前是从内存中得到的用户信息,那么考虑到可能数据是不实时的,就重新通过retrieveUser方法去取出用户信息,再次重复进行检查验证
if (cacheWasUsed) {
// There was a problem, so try again after checking
// we're using latest data (i.e. not from the cache)
cacheWasUsed = false;
user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
} else {
throw exception;
}
}
(6) //在spring的框架设计中经常能看到这样的前置处理和后置处理,此处后置处理只是判断了下用户的密码是否过期,如过期则记入日志
postAuthenticationChecks.check(user);
//如果没有缓存则进行缓存,则处的userCache是由NullUserCache类实现的,名如其义,该类的putUserInCache没做任何事
if (!cacheWasUsed) {
this.userCache.putUserInCache(user);
}
(7)
//以下代码主要是把用户的信息和之前用户提交的认证信息重新组合成一个authentication实例返回,返回类是
UsernamePasswordAuthenticationToken类的实例
Object principalToReturn = user;
if (forcePrincipalAsString) {
principalToReturn = user.getUsername();
}
return createSuccessAuthentication(principalToReturn, authentication, user);
-----------------------------------------------------------------------------------
代码分析到此,另外再附上类图方便理解。
- springSecurity登录验证分析——AbstractUserDetailsAuthenticationProvider
- springSecurity登录验证分析——AbstractUserDetailsAuthenticationProvider
- springSecurity的登录验证
- springSecurity的登录验证
- springSecurity的登录验证
- SpringSecurity———单点登录CAS
- SpringSecurity实现登录认证及权限验证
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- springSecurity源码分析——DelegatingFilterProxy类的作用
- SpringSecurity学习笔记(三)——自定义登录界面读取数据库用户以及权限
- Java内存分配、管理小结
- Android自由选择TextView的文字
- GDB调试总结__1
- Oracle中创建dblink的方法
- OCP-1Z0-051 第91题 TO_DATE转换函数
- springSecurity登录验证分析——AbstractUserDetailsAuthenticationProvider
- Adapter的继承结构
- ZeroMQ之消息丢失解决方法
- java + selenium测试框架 版本演化一
- openwrt在7620A上对fat格式U盘的支持
- bzero
- android json 处理
- 编程珠玑(第二版)读书笔记第一章
- LeetCode:Reverse Words in a String