在spring security3中使用自定义的MD5和salt进行加密

首先看代码:

<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder ref="myPasswordEncode">
<salt-source user-property="salt"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="myPasswordEncode" class="pw.bany.security.MyPasswordEncode">
<beans:constructor-arg name="encode" value="md5"></beans:constructor-arg>
</beans:bean>


如果我们要自己控制密码权限的验证,可以在配置中使用<password-encoder ref="myPasswordEncode">来指定自己的密码验证类,该类继承自MessageDigestPasswordEncoder。需要我们复写了public boolean isPasswordValid(String savePass, String submitPass, Object salt)方法,如果返回true,表示验证通过。上面代码还为MyPasswordEncode传入encode属性,来设置MyPasswordEncode中encode(本文下面的代码没有用到)。这样在isPasswordValid就可以用到需要加密的算法。isPasswordValid中savePass为数据库中加密保存的密码,submitPass为用户登录时提交的明文密码。 

@Override
// 如果返回true,则验证通过。
public boolean isPasswordValid(String savePass, String submitPass,
Object salt) {
return savePass.equalsIgnoreCase(Util.MD5WithSalt(submitPass,
salt.toString()));
}

Util.MD5WithSalt(submitPass,salt.toString()),是我们的加密方法,此处没贴出源码,网上很多。这里的salt需要特别注意一下,怎么才能把数据库中的salt传过来的问题。

上面配置中使用了<salt-source user-property="salt"/>来指定salt,但是系统是怎么知道在数据库中的salt字段呢?其实这里实际上是指定了org.springframework.security.core.userdetails.User中的一个属性,但是这个类中并没有这个属性,此时,需要我们重写这个类,为该类加入salt属性。

package pw.bany.security;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
public class SaltedUser extends User {
private String salt;
public SaltedUser(String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities, String salt) {
super(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
this.salt = salt;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
}

完成这里之后,还是不够的,因为重载的类只是有了这个属性,但是还是不知道如何从数据库中获取。要做到这个其实很简单,我们只需要修改myUserDetailsService中loadUserByUsername的返回值:

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
User user = null;
try {
user = userDao.getUserByName(username);
if (user == null)
throw new UsernameNotFoundException("用户" + username + "不存在!");
List<String> rolenames = userDao.loadRolesByUserName(username);
System.err.println("用户拥有角色有:");
for (String rolename : rolenames) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(
rolename);
auths.add(authority);
System.err.println(rolenames);
}
} catch (Exception e) {
e.printStackTrace();
}
System.err.println(auths.size());
boolean isEnabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
if (!user.getStatus().equalsIgnoreCase("enabled")) {
isEnabled = false;
}
return new SaltedUser(user.getUsername(), user.getPassword(),
isEnabled, accountNonExpired, credentialsNonExpired,
accountNonLocked, auths, user.getSalt());
}

如上面红色代码部分,一看便知。
 

原文地址:https://blog.csdn.net/zavens/article/details/17165833

转载于:https://www.cnblogs.com/jpfss/p/11022011.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值