有没有办法在 Keycloak 中配置 storageProviderTimeout?

Posted

技术标签:

【中文标题】有没有办法在 Keycloak 中配置 storageProviderTimeout?【英文标题】:Is there a way to configure the storageProviderTimeout in Keycloak? 【发布时间】:2021-09-12 20:54:48 【问题描述】:

我开发了User Storage SPI 的实现,它调用旧系统中的 API 来迁移用户。我需要为storageProviderTimeout 配置我自己的值,因为获得响应的时间很可能会超过默认的 3 秒。我已经将socket-timeout-millis 配置为在超时前超过默认的 5 秒,但这无济于事,因为storageProviderTimeout 的默认值为 3 秒。在查看 Keycloak 源代码时,特别是 AbstractStorageManager.java 提到了这个值是可配置的:

    /**
     * Timeouts are used as time boundary for obtaining models from an external storage. Default value is set
     * to 3000 milliseconds and it's configurable.
     */
    private static final Long STORAGE_PROVIDER_DEFAULT_TIMEOUT = 3000L;

读取配置值的函数如下所示:

    protected Long getStorageProviderTimeout() 
        if (storageProviderTimeout == null) 
            storageProviderTimeout = Config.scope(configScope).getLong("storageProviderTimeout", STORAGE_PROVIDER_DEFAULT_TIMEOUT);
        
        return storageProviderTimeout;
    

UserStorageManager 实例被创建(它扩展AbstractUserManager 时,构造函数使用以下代码实例化超类:

    public UserStorageManager(KeycloakSession session) 
        super(session, UserStorageProviderFactory.class, UserStorageProvider.class,
                UserStorageProviderModel::new, "user");
    

其中"user" 是稍后在getStorageProviderTimeout() 函数中传递给Config.scope() 的内容。

到目前为止,我尝试的是在standalone-ha.xml 中手动添加标签<user>,与<theme> 标签相同,如下所示:

            <user>
                <storageProviderTimeout>10000</storageProviderTimeout>
            </user>

但在启动 Keycloak 时,我收到此错误:

10:55:59,730 ERROR [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0055: Caught exception during boot: org.jboss.as.controller.persistence.ConfigurationPersistenceException: WFLYCTL0085: Failed to parse configuration
        at org.jboss.as.controller@15.0.1.Final//org.jboss.as.controller.persistence.XmlConfigurationPersister.load(XmlConfigurationPersister.java:143)
        at org.jboss.as.server@15.0.1.Final//org.jboss.as.server.ServerService.boot(ServerService.java:403)
        at org.jboss.as.controller@15.0.1.Final//org.jboss.as.controller.AbstractControllerService$1.run(AbstractControllerService.java:416)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.xml.stream.XMLStreamException: Unknown keycloak-server subsystem tag: user

我希望有人可以为我阐明这一点,因为我感觉好像遗漏了一些明显的东西。提前致谢!

【问题讨论】:

【参考方案1】:

正如此处https://keycloak.discourse.group/t/how-to-configure-storageprovidertimeout/9171 所讨论的,目前无法配置此属性。

有一个未解决的问题可以解决这个问题:https://issues.redhat.com/browse/KEYCLOAK-18856

作为一种临时快速而肮脏的解决方法,您可以在运行时通过反射设置值,例如您的自定义 UserStorageProvier 实现:

public class CustomUserStorageProviderFactory implements UserStorageProviderFactory<CustomUserStorageProvider> 

@Override
public void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) 
    UserProvider userProvider = session.userStorageManager();

    try 
        Field field = userProvider.getClass().getSuperclass().getDeclaredField("STORAGE_PROVIDER_DEFAULT_TIMEOUT");
        field.setAccessible(true);
        Field modifiers = field.getClass().getDeclaredField("modifiers");
        modifiers.setAccessible(true);
        modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(userProvider, 5000L);
     catch (NoSuchFieldException | IllegalAccessException e) 
        throw new RuntimeException(e);
    

【讨论】:

谢谢。此解决方法是目前唯一的解决方案,因此我将其标记为答案。现在这个问题已经被 Keycloak 团队提出并优先考虑,我们希望在下一个主要版本中看到它得到修复。

以上是关于有没有办法在 Keycloak 中配置 storageProviderTimeout?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法过滤/避免 keycloak SAML 断言中的重复属性名称?

有没有办法为我的自定义 Keycloak 电子邮件主题添加样式?

有没有办法使用 cypress/JS 以编程方式通过 Keycloak 登录应用程序?

有没有办法在不使用其 UI 的情况下使用 KeyCloak 身份验证?

有没有办法使用 Keycloak Admin REST API 将用户添加到 Keycloak 中的多个组(批量)?

有没有办法使用 Keycloak API 检索组中的成员数量?