有没有一种方法可以在Keycloak中配置storageProviderTimeout?

3
我已经开发了一个实现用户存储SPI的程序,调用遗留系统中的API以迁移用户。 由于存在偶发可能需要超过默认的3秒才能获得响应,因此我需要配置自己的storageProviderTimeout值。 我已经将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() 中设置存储提供者超时时间。

到目前为止我尝试手动将标签 <user> 添加到 standalone-ha.xml 文件中与 <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

希望有人能为我解决这个问题,因为感觉自己漏看了什么显而易见的东西。提前致谢!

2个回答

2
在Keycloak/Quarkus(v17.0.0)中,您可以在keycloak.conf文件中指定参数spi-user-storage-provider-timeout
例如(10秒): spi-user-storage-provider-timeout=10000

谢谢!你在文档中找到了吗?链接是什么? - MhagnumDw

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);
    }
}

}


1
谢谢。目前这个解决方法是唯一的解决方案,所以我会将其标记为答案。现在这个问题已经被提出并与Keycloak团队优先处理,我们希望在下一个主要版本中能够看到它得到修复。 - Steven Hovland
谢谢你提供的解决方法,但是你测试过哪个版本的Keycloak呢?因为我在v15.1.1版本中仍然会遇到3000毫秒的异常。 - Phael
这种对私有静态最终字段的反射访问在Java 17中将不再起作用! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接