密码加密登录是为了提高系统安全性,即使是管理员查看数据库也得不到密码。
用户在登录时所输入的密码都是明文的,数据库中存的密码是明文加密之后的,因此就必须将用户输入之后的密码进行加密再去跟数据库进行对比。
而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密码,如果能反推回来那这个加密是没有意义的。其中MD5是目前比较可靠的不可逆的加密方式,因此我们可以通过MD5来对密码进行加密。
重写setCredentialsMatcher()方法
在 Realm 类中重写setCredentialsMatcher()方法,此方法用于设置加密码算法:
1 2 3 4 5 6 7
|
@Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5");//md5加密方式 hashedCredentialsMatcher.setHashIterations(1024);//加密次数 super.setCredentialsMatcher(hashedCredentialsMatcher); }
|
该方法中使用的是 HashedCredentialsMatcher 类设置加密算法,此处设置的是md5加密方式和加密次数1024次。设置完上面的密码匹配类之后,就可以将用户的登录密码自动加密为MD5。
注:别忘了改super.setCredentialsMatcher()里面的参数是hashedCredentialsMatcher。
重写doGetAuthenticationInfo()认证方法
在 Realm 类中重写 doGetAuthenticationInfo() 认证方法,该方法用于认证,可以对登录时所输入的密码进行加密加盐:
什么是盐:并不是炒菜的调料,而是为了提高加密的安全性,简单来说就是:MD5加密之后再进行了一层加密。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
/** * 重写的自定义认证方法 * @param authenticationToken 该认证Token对象封装了用户名、密码等信息 * @return 认证信息 * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //认证Token转换为常用的用户名和密码Token UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; User user = userService.findByUserName(token.getUsername()); if (user == null) return null;//抛出用户不存在 //该盐值可以是已经存在数据库中的盐值字段,也可以是当前用户名(但不推荐),一般盐值都是唯一不变的字段 ByteSource salt = ByteSource.Util.bytes(user.getSalt()); String credential = user.getPassword(); return new SimpleAuthenticationInfo( user, //用户对象 credential, //用户密码 salt, //用户盐值,如果不想加盐即可省略该参数 this.getName()); }
|
查看密码加密和密码对比
因为我们用的是MD5加密方式,那么按两下Shift键搜索 HashedCredentialsMatcher 类,找到 doCredentialsMatch() 方法,该方法中就进行了密码加密和密码对比。
在 doCredentialsMatch() 方法中打个断点进行进行调试,可以看到下图中的结果:
结论:MD5加密方式的密码加密和密码对比都是在 HashedCredentialsMatcher 类中的 doCredentialsMatch() 方法进行的。
近期评论