0
点赞
收藏
分享

微信扫一扫

Spring Security - 密码加密

前端王祖蓝 2021-09-28 阅读 147

密码加密

Spring Security 内置了加密机制

只需要实现PasswordEncoder接口即可

接入BCrypt加密

自定义自己的加密类继承BCryptPasswordEncoder

package com.yang.springsecurity.provider;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;

@Component
public class MyPasswordEncoder extends BCryptPasswordEncoder {
    private Pattern BCRYPT_PATTERN = Pattern
            .compile("\\A\\$2(a|y|b)?\\$(\\d\\d)\\$[./0-9A-Za-z]{53}");

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        //判断系统之前的用户是否是采用bcrypt加密,不是的就采用明文匹配
        if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()){
            return rawPassword.toString().matches(encodedPassword);
        }
        return super.matches(rawPassword, encodedPassword);
    }
}

修改配置应用自己的加密

@Autowired
private MyPasswordEncoder myPasswordEncoder;

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    //添加AuthenticationProvider
    auth.userDetailsService(myUserDetailsService).passwordEncoder(myPasswordEncoder);
}

注意:

新系统引入密码加密,只需指定明确加密方式即可。

但如果老系统使用明文或者其它加密方式,现在要引入bcrypt加密方式可采用以下几种方式

  • 兼容

    重新matches()方法,判断系统之前的用户是否是采用bcrypt加密,不是的就采用明文匹配

  • 增量更新

    判断系统之前的用户是否是采用bcrypt加密,不是的就采用明文匹配,则尝试使用用户输入的密码重新生成BCrypt密文,并写回数据库。

  • 以旧的加密方案作为基础接入BCrypt加密。

例如,旧的方案是MD5加密,即数据库中的所有

密码都是 MD5形式的密码,那么直接把这些密码当作明文,先“跑库”生成 BCrypt 密文,再使用

encode 和 matches 两个方法在执行 BCrypt 加密之前都先用MD5运算一遍即可。

SpringSecurity5.x 加密方式采用{Id}password的格式配置,这样做迁移的时候系统可以兼容多种加密方式。

我们可以看一下PasswordEncoderFactories自带的加密方式

public class PasswordEncoderFactories {
    public static PasswordEncoder createDelegatingPasswordEncoder() {
        String encodingId = "bcrypt";
        Map<String, PasswordEncoder> encoders = new HashMap();
        encoders.put(encodingId, new BCryptPasswordEncoder());
        encoders.put("ldap", new LdapShaPasswordEncoder());
        encoders.put("MD4", new Md4PasswordEncoder());
        encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
        encoders.put("noop", NoOpPasswordEncoder.getInstance());
        encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
        encoders.put("scrypt", new SCryptPasswordEncoder());
        encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
        encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
        encoders.put("sha256", new StandardPasswordEncoder());
        encoders.put("argon2", new Argon2PasswordEncoder());
        return new DelegatingPasswordEncoder(encodingId, encoders);
    }

    private PasswordEncoderFactories() {
    }
}

举报

相关推荐

0 条评论