Keycloak自定义用户存储不显示属性

Mat*_*t.C 6 java mysql keycloak

我在 keycloak 中实现了一个自定义用户存储 spi,用于与 mysql 数据库通信。除了特定的情况外,它都以正确的方式工作。

当我转到管理控制台中的用户页面并单击查看所有用户时,检索到的用户将正确显示所有字段(用户名、电子邮件、姓氏、名字)

在此输入图像描述

从上图中,前两个用户是直接从 keycloak 创建的,后两个是从 mysql 数据库检索的。

相反,当我单击打开的页面中的单个用户时,除了用户 ID用户名之外的所有字段都是空的。

在此输入图像描述

我不明白为什么在视图中所有页面中这些数据都正确显示,而在单用户页面中则不然。我想这是因为 kecloak 尝试从它自己的存储中读取数据,因为

  • 如果我将其设置为具有自定义值的单用户页面中的电子邮件字段并保存
  • 碰巧在查看所有页面中,电子邮件具有图像中的值(mc..@hotmail.it)
  • 单用户页面中它有另一个值(我保存的自定义值)。

由于存储是使用我写的https://github.com/Linch1/mysql-keycloak-storage-spi(主要登录位于 jar-module 文件夹中)。我认为这种行为的主角是UserAdapter.java文件,在我的文件中我是这样写的:

package mysql.storage.main;

import org.keycloak.component.ComponentModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage;

import lombok.extern.jbosslog.JBossLog;
import mysql.storage.entity.User;

@JBossLog
public class UserAdapter extends AbstractUserAdapterFederatedStorage {

  private final User user;
  private final String keycloakId;
  

  
  public UserAdapter(KeycloakSession session, RealmModel realm, ComponentModel model, User user) {
    super(session, realm, model);
    this.user = user;
    this.EMAIL_ATTRIBUTE = user.getEmail();
    this.keycloakId = StorageId.keycloakId(model, String.valueOf(user.getId()) ); 
  }

  @Override
  public String getId() {
    return keycloakId;
  }

  @Override
  public String getUsername() {
      log.infov("\n UserAdapter > getting username: " + user.getNickName() );
    return user.getNickName();
  }

  @Override
  public void setUsername(String username) {
    user.setNickName(username);
  }

  @Override
  public String getEmail() {
      log.infov("\n UserAdapter > getting email: " + user.getEmail() );
    return user.getEmail();
  }

  @Override
  public void setEmail(String email) {
    user.setEmail(email);
  }

  @Override
  public String getFirstName() {
    return user.getFirstName();
  }

  @Override
  public void setFirstName(String firstName) {
    user.setFirstName(firstName);
  }

  @Override
  public String getLastName() {
    return user.getLastName();
  }

  @Override
  public void setLastName(String lastName) {
    user.setLastName(lastName);
  }
}

Run Code Online (Sandbox Code Playgroud)

我阅读了文档并搜索了一段时间,但没有发现任何有用的东西。有任何想法吗?

Kai*_*tsu 4

我认为这可能与您的提供商的用户查找优先级和缓存有关。

尝试将您的提供商的配置(管理控制台 > 用户联合 > 您的提供商)优先级编辑为低于 0 的值(注意其他提供商的配置和优先级),以便它首先在您的自定义提供商中查找它。

此外,您可能想检查缓存策略值,尝试将其设置为 NO_CACHE 或为 MAX_LIFESPAN 组合框设置一个值。