若依Vue前后端分离版本自定义加密方式
最近在学习若依vue前后端分离版的脚手架,想使用Md5加密方式实现登陆验证,现在记录一下解决过程。
若依是个很好的脚手架,单体版若依使用shiro实现安全认证与权限控制,而分离版使用的是Spring Security实现,我们阅读若依源码时可以发现,若依的framework模块下有个security包,这里面是若依自己封装的认证失败处理类等,与加密登录验证无关,跳过。我们需要关注的是framework模块下的config包下的SecurityConfig类,里面有两个方法:
/**
* 强散列哈希加密实现
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{
return new BCryptPasswordEncoder();
}
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
Spring Security通过passwordEncoder()进行身份认证,参数为PasswordEncoder接口类,也就是说传入的参数是需要实现PasswordEncoder接口的类,BCryptPasswordEncoder类是强散列哈希类,关于这个类的说明我们在此不介绍,它是一种哈希算法,详情自行百度,既然知道身份认证使用的方法了,咱们自定义一个Md5加密方法:
/**
* Md5加密实现
* @return
*/
@Bean
public Md5PasswordEncoder md5PasswordEncoder(){
return new Md5PasswordEncoder();
}
在common模块下新建一个类Md5PasswordEncoder并实现PasswordEncoder接口
public class Md5PasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
return Md5Utils.hash(rawPassword.toString());
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return Md5Utils.hash(rawPassword.toString()).equals(encodedPassword);
}
}
若依自己封装了一个Md5加密的util类,我们不用自己封装了,但还是把代码贴出来吧
package com.ruoyi.common.utils.sign;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Md5加密方法
*
* @author ruoyi
*/
public class Md5Utils
{
private static final Logger log = LoggerFactory.getLogger(Md5Utils.class);
private static byte[] md5(String s)
{
MessageDigest algorithm;
try
{
algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(s.getBytes("UTF-8"));
byte[] messageDigest = algorithm.digest();
return messageDigest;
}
catch (Exception e)
{
log.error("MD5 Error...", e);
}
return null;
}
private static final String toHex(byte hash[])
{
if (hash == null)
{
return null;
}
StringBuffer buf = new StringBuffer(hash.length * 2);
int i;
for (i = 0; i < hash.length; i++)
{
if ((hash[i] & 0xff) < 0x10)
{
buf.append("0");
}
buf.append(Long.toString(hash[i] & 0xff, 16));
}
return buf.toString();
}
public static String hash(String s)
{
try
{
return new String(toHex(md5(s)).getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
}
catch (Exception e)
{
log.error("not supported charset...{}", e);
return s;
}
}
}
好了,到这我们实现了登录的密码验证以md5的方式验证,但还有一步,那就是加密,比如注册账户、修改密码的时候,我们需要将密码加密以后存入数据库,若依的加密方法在common模块的SecurityUtils类中,我们将原来的方法注释掉,替换为使用Md5加密
/**
* 生成BCryptPasswordEncoder密码
* 修改为md5加密
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPassword(String password)
{
//BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//return passwordEncoder.encode(password);
return Md5Utils.hash(password);
}
/**
* 判断密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后字符
* @return 结果
*/
public static boolean matchesPassword(String rawPassword, String encodedPassword)
{
// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
// return passwordEncoder.matches(rawPassword, encodedPassword);
Md5PasswordEncoder md5PasswordEncoder=new Md5PasswordEncoder();
return md5PasswordEncoder.matches(rawPassword,encodedPassword);
}
这样就修改了若依框架的密码加密、登陆验证方式了,我也从中学习到了SpringSecurity的使用方法与登录流程原理。