【问题标题】:How to get username inside CustomPasswordEncoder in SpringSecurity?如何在 Spring Security 的 Custom PasswordEncoder 中获取用户名?
【发布时间】:2015-12-06 14:53:12
【问题描述】:

我在现有应用程序中引入 Spring Security。目前 db 有我们想要迁移到 bcrypt 的 MD5 编码密码。由于我们最初拥有大量用户,我们希望同时支持 MD5 和 bcrypt。我们已经考虑过有一个表来存储有多少用户迁移到 bcrypt,一旦我们迁移了每个用户,我们将停止支持 MD5。

所以我想到了扩展 SpringSecurity 的 BCryptPasswordEncoder 类并在matches方法中做一些事情。所以我有下课,

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

public class CustomPasswordEncoder extends BCryptPasswordEncoder {

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        if (rawPassword == null || encodedPassword == null) {
            return false;
        }

        if (!super.matches(rawPassword, encodedPassword)) { // This is not BCrypt password try OLD password encoding instead
            boolean isOldPasswordMatched = rawPassword.equals(SHA1.getSHA1Hash(encodedPassword));
            if(isOldPasswordMatched){
                migrateToBCrypt(userName /* error here*/, encode(rawPassword));
            }
            return isOldPasswordMatched;
        }
        return true;
    }

    private boolean migrateToBCrypt(String userName, String newBcryptPassword){
        //update password in database 
        //Insert to migrated table
        return true;
    } 
}

但是我的问题是我没有在此函数中获取用户名来进行迁移,如何在密码编码器的匹配()中获取用户名?我在这里做错了吗?在这种情况下,最好的方法是什么?

【问题讨论】:

  • @user1354678 : 作者目前无法获取用户本身,当用户名本身未知时,您希望他/她如何检查passwordType?
  • @user1354678 我无法在此函数中获取用户名
  • @aProgrammer,我已经提出了答案,看看吧
  • @user1354678 目前我的设置中没有 userService 类实现。所以明天我会尝试,我还必须想办法将你的答案转换为 XML 配置。谢谢

标签: java jakarta-ee spring-security passwords bcrypt


【解决方案1】:

提出的逻辑只是我的想法,您可以根据需要进行修改。

public class UserService extends BCryptPasswordEncoder{

    public Response login(@RequestBody User user){

        User existingUser = UserDao.getInstance().getUserByUsername( user.getUsername() );

        //Assuming all the users have `PasswordType` column as "MD5" in user table
        if( existingUser.getPasswordType().equals("MD5") ){
                // Your MD5 verification method, return boolean
            if( verifyMD5(user.getPassword, existingUser.getPassword()) ){
                 migrateToBCrypt(existingUser, user);
                 return Response.status(200).entity("Successfully Logged in").build();
            }else{
                 return Response.status(400).entity("Invalid Credentials").build();
            }

        }else if( existingUser.getPasswordType().equals("BCrypt") ){

            if( matches(user.getPassword(), existingUser.getPassword()) ){
                return Response.status(200).entity("Successfully Logged in").build();
            }else{
                return Response.status(400).entity("Invalid Credentials").build();
            }

        }

    }

    private void migrateToBcrypt(User existingUser, User user){

        existingUser.setPassword( encode(user.getPassword()) );
        existingUser.setPasswordType( "Bcrypt" );
        UserDao.getInstance().updateUser( existingUser );

    }

}

或者如果您不想在表格中引入另一列,

public class UserService extends BCryptPasswordEncoder{

    public Response login(@RequestBody User user){

        User existingUser = UserDao.getInstance().getUserByUsername( user.getUsername() );

        if( !existingUser.getPassword().startsWith("$") ){
                // Your MD5 verification method, return boolean
            if( verifyMD5(user.getPassword, existingUser.getPassword()) ){
                 migrateToBCrypt(existingUser, user);
                 return Response.status(200).entity("Successfully Logged in").build();
            }else{
                 return Response.status(400).entity("Invalid Credentials").build();
            }

        }else {

            if( matches(user.getPassword(), existingUser.getPassword()) ){
                return Response.status(200).entity("Successfully Logged in").build();
            }else{
                return Response.status(400).entity("Invalid Credentials").build();
            }

        }

    }

    private void migrateToBcrypt(User existingUser, User user){

        existingUser.setPassword( encode(user.getPassword()) );
        UserDao.getInstance().updateUser( existingUser );

    }

}

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 2014-05-26
    • 2014-05-25
    • 2013-06-30
    • 2021-08-30
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2013-07-02
    相关资源
    最近更新 更多