Spring Security - 密碼加密

密碼加密

Spring Security 內(nèi)置了加密機(jī)制

只需要實(shí)現(xiàn)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) {
        //判斷系統(tǒng)之前的用戶是否是采用bcrypt加密,不是的就采用明文匹配
        if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()){
            return rawPassword.toString().matches(encodedPassword);
        }
        return super.matches(rawPassword, encodedPassword);
    }
}

修改配置應(yīng)用自己的加密

@Autowired
private MyPasswordEncoder myPasswordEncoder;

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

注意:

新系統(tǒng)引入密碼加密,只需指定明確加密方式即可。

但如果老系統(tǒng)使用明文或者其它加密方式,現(xiàn)在要引入bcrypt加密方式可采用以下幾種方式

  • 兼容

    重新matches()方法,判斷系統(tǒng)之前的用戶是否是采用bcrypt加密,不是的就采用明文匹配

  • 增量更新

    判斷系統(tǒng)之前的用戶是否是采用bcrypt加密,不是的就采用明文匹配,則嘗試使用用戶輸入的密碼重新生成BCrypt密文,并寫回?cái)?shù)據(jù)庫。

  • 以舊的加密方案作為基礎(chǔ)接入BCrypt加密。

例如,舊的方案是MD5加密,即數(shù)據(jù)庫中的所有

密碼都是 MD5形式的密碼,那么直接把這些密碼當(dāng)作明文,先“跑庫”生成 BCrypt 密文,再使用

encode 和 matches 兩個(gè)方法在執(zhí)行 BCrypt 加密之前都先用MD5運(yùn)算一遍即可。

SpringSecurity5.x 加密方式采用{Id}password的格式配置,這樣做遷移的時(shí)候系統(tǒng)可以兼容多種加密方式。

我們可以看一下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() {
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容