- 增加一个Md5PasswordEncoder
来继承PasswordEncoder,实现encode和matches两个方法,实现自定义加密逻辑
项目中增加一个Md5PasswordEncoder类
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* md5密码编码器
*
* @author admin
* @date 2024/08/19
*/
@Component("mPasswordEncoder")
public class Md5PasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
String salt = "";
return EncryptMD5(rawPassword.toString(), salt);
}
/**
* 编码
*
* @param rawPassword 原始密码
* @param salt 盐
* @return {@link String }
*/
public String encode(CharSequence rawPassword, String salt) {
return EncryptMD5(rawPassword.toString(), salt);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
String salt = "";
return encodedPassword.equals(EncryptMD5(rawPassword.toString(), salt));
}
/**
* 验证
*
* @param rawPassword 原始密码
* @param encodedPassword 编码密码
* @param salt 盐
* @return boolean
*/
public boolean matches(CharSequence rawPassword, String encodedPassword, String salt) {
return encodedPassword.equals(EncryptMD5(rawPassword.toString(), salt));
}
public static final String JST = "Jst";
public static final String SYSTEM = "system";
/**
* 使用MD5算法对输入字符串进行加密,并返回类似于"XX-XX-XX-..."的十六进制格式
*
* @param password 明文密码
* @param salt 盐值
* @return 格式化的MD5哈希值
*/
public static String EncryptMD5(String password, String salt) {
try {
String input = JST + password + SYSTEM + salt;
// 获取MD5实例
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算哈希值
byte[] hash = md.digest(input.getBytes());
// 将哈希值转换为十六进制格式的字符串,并添加分隔符
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex.toUpperCase()).append("-");
}
// 删除最后一个多余的 "-"
return hexString.substring(0, hexString.length() - 1);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}
}
- 自定义MD5身份验证器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
/**
* 自定义MD5身份验证提供程序
*
* @author admin
* @date 2024/08/19
*/
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
@Qualifier("userDetailsServiceImpl")
private UserDetailsService userDetailsService;
@Autowired
@Qualifier("mPasswordEncoder")
private Md5PasswordEncoder passwordEncoder; // 使用你的自定义PasswordEncoder
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String rawPassword = (String) authentication.getCredentials();
// 从数据库或其他数据源加载用户
UserDetails user = userDetailsService.loadUserByUsername(username);
// 获取用户的盐值(假设User对象有一个getSalt方法)
String salt = ((LoginUser) user).getSalt();
// 验证密码
if (passwordEncoder.matches(rawPassword, user.getPassword(), salt)) {
return new UsernamePasswordAuthenticationToken(
user, user.getPassword(), user.getAuthorities());
} else {
throw new BadCredentialsException("Bad credentials");
}
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
- SecurityConfig类中引用
/**
* 自定义MD5身份验证器
*/
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
/**
* 强散列哈希加密实现
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if (!casProperties.isCasEnable()) {
// 账号密码的验证
// auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
auth.userDetailsService(userDetailsService).passwordEncoder(md5PasswordEncoder());
auth.authenticationProvider(customAuthenticationProvider);
}
// cas
if (casProperties.isCasEnable()) {
super.configure(auth);
auth.authenticationProvider(casAuthenticationProvider());
}
}
// 上一步我们的Md5PasswordEncoder
@Bean
public Md5PasswordEncoder md5PasswordEncoder() {
return new Md5PasswordEncoder();
}
- SecurityUtils类中修改
/**
* 生成BCryptPasswordEncoder密码
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPassword(String password) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.encode(password);
}
/**
* 生成MD5密码
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPasswordMD5(String password, String salt) {
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
return md5PasswordEncoder.encode(password, salt);
}
/**
* 判断密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后字符
* @return 结果
*/
public static boolean matchesPassword(String rawPassword, String encodedPassword) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.matches(rawPassword, encodedPassword);
}
/**
* 判断MD5密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后字符
* @param salt 盐值
* @return 结果
*/
public static boolean matchesPasswordMD5(String rawPassword, String encodedPassword, String salt) {
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
return md5PasswordEncoder.matches(rawPassword, encodedPassword, salt);
}
- 在UserDetailsServiceImpl中修改
/*若依框架自带的密码验证*/
// passwordService.validate(user);
/*使用自定义MD5加盐密码验证*/
passwordService.validateMD5(user);
这样就可以了