若依前后端分离项目修改登录加密方式(MD5+盐值)

  1. 增加一个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);
        }
    }
}
  1. 自定义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);
    }
}
  1. 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();
    }

  1. 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);
}
  1. 在UserDetailsServiceImpl中修改
        /*若依框架自带的密码验证*/
        // passwordService.validate(user);
        /*使用自定义MD5加盐密码验证*/
        passwordService.validateMD5(user);

这样就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值