Spring security用户验证机制浅谈.
2015-11-20 19:32
411 查看
1. 首先CustomUserDetailsService需要实现UserDetailsService(org.springframework.security.core.userdetails.UserDetailsService)接口,实现获取用户Detail信息的回调函数.必须要实现的方法是loadUserByUsername
注意: 这里的user类必须继承userDetail类,并且必须继承
private String
password;
private String
username;
private Set<GrantedAuthority>
authorities;
private booleanaccountNonExpired;
private booleanaccountNonLocked;
private booleancredentialsNonExpired;
这五个属性
和hashCode, equals这两个方法;
构造方法中必须给上述的5个属性赋值, CustomUserDetailsService调用构造方法,生成一个user对象;
如果user不存在,这里可以直接抛出UsernameNotFoundException异常,具体流程自己试验下,前台SPRING_SECURITY_LAST_EXCEPTION显示的错误是:”坏的凭证”
2. loadUserByUsername方法返回后会跳到DaoAuthenticationProvider(org.springframework.security.authentication.dao.DaoAuthenticationProvider)类中retrieveUser方法中
3. retrieveUser方法返回后会跳到
AbstractUserDetailsAuthenticationProvider(org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider)
authenticate方法中,这个方法会先到缓存中查找user:
String username =(authentication.getPrincipal() ==null) ?"NONE_PROVIDED"
: authentication.getName();
boolean cacheWasUsed =true;
UserDetails user =this.userCache.getUserFromCache(username);
如果没有的话会从上一步DaoAuthenticationProvider的loadUserByUsername方法把user查出来。这里会抛UsernameNotFoundException这个异常,应该是用户不存在这个错误,即Bad
credentials.
4. authenticate方法里面
preAuthenticationChecks.check(user);这里进行基本有效性验证(是否有效,是否被锁,是否过期);代码如下:
if (!user.isAccountNonLocked()) {
thrownew
LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked",
"User account is locked"), user);
}
if (!user.isEnabled()) {
thrownew
DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled",
"User is disabled"), user);
}
if (!user.isAccountNonExpired()) {
thrownew
AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired",
"User account has expired"), user);
}
5. authenticate方法里面
additionalAuthenticationChecks(user,(UsernamePasswordAuthenticationToken) authentication);这里进行密码验证.
additionalAuthenticationChecks调用的是DaoAuthenticationProvider(org.springframework.security.authentication.dao.DaoAuthenticationProvider)中的additionalAuthenticationChecks的方法;
应该是继承的关系;
具体比较的方法写在 Md4PasswordEncoder(org.springframework.security.authentication.encoding.Md5PasswordEncoder)类中的
public boolean isPasswordValid(String encPass, String rawPass, Object salt) 方法中; 可是debug中中不到
Md5PasswordEncoder实现的isPasswordValid方法; 这很蹊跷...不过根据配置文件中; 加密方式应该是md5;
<!-- 用户的密码加密或解密 -->
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<!-- 注意能够为authentication-manager 设置alias别名 -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsManager">
<password-encoder ref="passwordEncoder">
<salt-source user-property="username" />
</password-encoder>
</authentication-provider>
</authentication-manager>
所以应该Md5PasswordEncoder也有实现isPasswordValid(String encPass, String rawPass, Object salt)这个方法;
至于前台password怎么传到这里; spring security拦截了j_spring_security_check请求; 并把j_password赋给了DaoAuthenticationProvider(org.springframework.security.authentication.dao.DaoAuthenticationProvider)中passwordEncoder属性;
这个还没验证过;
注意: 这里的user类必须继承userDetail类,并且必须继承
private String
password;
private String
username;
private Set<GrantedAuthority>
authorities;
private booleanaccountNonExpired;
private booleanaccountNonLocked;
private booleancredentialsNonExpired;
这五个属性
和hashCode, equals这两个方法;
构造方法中必须给上述的5个属性赋值, CustomUserDetailsService调用构造方法,生成一个user对象;
如果user不存在,这里可以直接抛出UsernameNotFoundException异常,具体流程自己试验下,前台SPRING_SECURITY_LAST_EXCEPTION显示的错误是:”坏的凭证”
2. loadUserByUsername方法返回后会跳到DaoAuthenticationProvider(org.springframework.security.authentication.dao.DaoAuthenticationProvider)类中retrieveUser方法中
3. retrieveUser方法返回后会跳到
AbstractUserDetailsAuthenticationProvider(org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider)
authenticate方法中,这个方法会先到缓存中查找user:
String username =(authentication.getPrincipal() ==null) ?"NONE_PROVIDED"
: authentication.getName();
boolean cacheWasUsed =true;
UserDetails user =this.userCache.getUserFromCache(username);
如果没有的话会从上一步DaoAuthenticationProvider的loadUserByUsername方法把user查出来。这里会抛UsernameNotFoundException这个异常,应该是用户不存在这个错误,即Bad
credentials.
4. authenticate方法里面
preAuthenticationChecks.check(user);这里进行基本有效性验证(是否有效,是否被锁,是否过期);代码如下:
if (!user.isAccountNonLocked()) {
thrownew
LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked",
"User account is locked"), user);
}
if (!user.isEnabled()) {
thrownew
DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled",
"User is disabled"), user);
}
if (!user.isAccountNonExpired()) {
thrownew
AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired",
"User account has expired"), user);
}
5. authenticate方法里面
additionalAuthenticationChecks(user,(UsernamePasswordAuthenticationToken) authentication);这里进行密码验证.
additionalAuthenticationChecks调用的是DaoAuthenticationProvider(org.springframework.security.authentication.dao.DaoAuthenticationProvider)中的additionalAuthenticationChecks的方法;
应该是继承的关系;
具体比较的方法写在 Md4PasswordEncoder(org.springframework.security.authentication.encoding.Md5PasswordEncoder)类中的
public boolean isPasswordValid(String encPass, String rawPass, Object salt) 方法中; 可是debug中中不到
Md5PasswordEncoder实现的isPasswordValid方法; 这很蹊跷...不过根据配置文件中; 加密方式应该是md5;
<!-- 用户的密码加密或解密 -->
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<!-- 注意能够为authentication-manager 设置alias别名 -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsManager">
<password-encoder ref="passwordEncoder">
<salt-source user-property="username" />
</password-encoder>
</authentication-provider>
</authentication-manager>
所以应该Md5PasswordEncoder也有实现isPasswordValid(String encPass, String rawPass, Object salt)这个方法;
至于前台password怎么传到这里; spring security拦截了j_spring_security_check请求; 并把j_password赋给了DaoAuthenticationProvider(org.springframework.security.authentication.dao.DaoAuthenticationProvider)中passwordEncoder属性;
这个还没验证过;
相关文章推荐
- Spring Security 项目
- spring transaction源码分析--事务架构
- Maven在Myeclipse上配置
- 用Ant实现Java项目的自动构建和部署
- myeclipse中自动提示的设置
- “java.lang.NoClassDefFoundError: javax/mail/Address”解决办法
- java 类文件类型
- 判断两个时间段是否重合
- 关于eclipse创建android项目无法创建class的问题
- java反射和注解
- 如何使用struts2搭建web项目
- java 创建文件 写入内容 读取内容
- Java中各种Stream和Reader,write
- Java学习之Hessian通信基础
- android studio 导入 eclipse 并上传到svn
- spring的aop编程
- jdk安装后eclipse启动报无VM machine错误解决
- Java集合---LinkedList源码解析
- java 中的Scanner
- Java基础08 继承