有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在SpringSecurity的CustomPasswordEncoder中获取用户名?

我将在现有应用程序中引入Spring安全性。目前db有MD5编码的密码,我们希望将其迁移到bcrypt。由于我们最初拥有大量用户,我们希望同时支持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;
    } 
}

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


共 (1) 个答案

  1. # 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 );
    
        }
    
    }