Keycloak 用户 SPI 迁移策略导入 - 导入凭据失败

问题描述 投票:0回答:1

我正在努力从旧的数据库存储中迁移出来。我们创建了一个用户存储 SPI,允许我们使用旧系统来验证凭据。目前这有效。我们在自定义 CredentialInputValidator.isValid 函数中验证凭据。我们想要做的是,旧系统的登录是有效的,我们想要创建一个与用户匹配的本地用户帐户并附加凭据。

据我了解,这应该工作的方式是:

Login ->
        -> Hits Custom User Storage SPI
        -> On Success
            -> Create local user account if not exists
            -> Attach new password credentials
        -> Is Logged In
    Log Out
    Log In ->
        -> Checks Keycloak Local Users
            -> User Storage SPI is never checked, because the local account was previously created.
        -> UN/PW check
            -> (failure happens here)
        -> Is Logged In

这就是它应该如何工作。不幸的是,无论我尝试什么,它都不会让我第二次登录(也不会尝试再次访问用户存储 SPI,因为本地帐户存在)。我可以看到用户和凭据是在用户下的领域中创建的;我可以在 public.user_entity 和 public.credential 表中看到用户和凭证行。

无论我如何尝试,我都无法登录本地帐户。

下面是我的 isValid 函数。谁能帮我找出我做错了什么?


        @Override
        public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) {
            UserCredentialModel cred = (UserCredentialModel)input;
            String password = cred.getValue();
    
            // Login to the legacy system.
            String loginOutput = loginCMD(user.getUsername(), password, xForwardedFor);
    
            // Falures return a simple string "false"
            Boolean valid = !loginOutput.equals("false");
    
            if (!valid) {
                return valid;
            }
    
            // Store the user back to Keycloak.
            UserModel local = UserStoragePrivateUtil.userLocalStorage(session).getUserByUsername(realm, user.getUsername());
    
            if (local != null) {
                return valid;
            }
    
            local = UserStoragePrivateUtil.userLocalStorage(session).addUser(realm, user.getUsername());
            local.setFirstName("firstName");
            local.setLastName("lastName");
            local.setEmail(user.getUsername());
            local.setEnabled(true);
            local.setUsername(user.getUsername());
    
            Pbkdf2PasswordHashProvider encoder = new Pbkdf2PasswordHashProvider(
                Pbkdf2Sha512PasswordHashProviderFactory.ID,
                Pbkdf2Sha512PasswordHashProviderFactory.PBKDF2_ALGORITHM,
                Pbkdf2Sha512PasswordHashProviderFactory.DEFAULT_ITERATIONS,
                256 // Tried setting this to 512, as well, no dice.
            );
    
            PasswordCredentialModel pcm = encoder.encodedCredential(password, Pbkdf2Sha512PasswordHashProviderFactory.DEFAULT_ITERATIONS);
    
            Date date = new Date();
            pcm.setCreatedDate(date.getTime());
            pcm.setUserLabel("user-spi migration");
    
            if (!local.credentialManager().isConfiguredFor(input.getType())) {
                try {
                    local.credentialManager().createStoredCredential(pcm);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            return valid;
        }

我尝试使用凭据创建本地用户,并使用该帐户登录。帐户和凭据已创建,但登录始终失败并显示

DEBUG [org.keycloak.credential.PasswordCredentialProvider](executor-thread-1)用户[已编辑]密码验证失败

java keycloak
1个回答
0
投票

您需要实现两个接口UserLookupProvider、CredentialInputValidator。

提到 LookupProvider 是在方法 getUserByUsername 上预先调用的,这必须返回一个有效的用户对象。仅当成功时,才会调用 isValid 方法。

© www.soinside.com 2019 - 2024. All rights reserved.