我使用Keycloak版本19.0.1和自定义用户存储SPI从现有的遗留数据库加载用户。我通过提到的用户存储SPI向Keycloak用户表示模型添加了一些自定义属性。这些自定义属性是Keycloak在调用/token
端点时发出的JWT令牌的一部分。
当调用/token
端点时,Keycloak会按预期使用自定义属性发出JWT令牌。然而,当遗留数据库中的用户从遗留应用程序更新时,keycloak仍然会发出具有过时自定义属性值的JWT令牌。我相信这是Keycloak中的缓存问题,但无法找到正确的缓存选项来禁用缓存,并始终为发布的JWT令牌获取最新的自定义属性值。Keycloak似乎默认支持各种不同的本地和分布式缓存,可以使用XML文件进行配置:
- https://www.keycloak.org/server/caching
- https://wjw465150.gitbooks.io/keycloak-documentation/content/server_installation/topics/cache/eviction.html
我使用默认的缓存模式,根据文档是Infinispan。到目前为止,我已经尝试了以下方法(见下面的docker图像):
- 构建keycloak时传递
kc.sh build --spi-user-cache-infinispan-enabled=false
选项 - 在构建阶段传递环境变量
KC_SPI_USER_CACHE_DEFAULT_ENABLED=false
- 设置
NO_CACHE
政策上的用户fedaration,但似乎有一个大的和自定义属性与此选项在Keycloak 19版本失踪:https://github.com/keycloak/keycloak/issues/10826(因此现在对我来说不是一个选择)
我应该使用什么缓存配置来始终获取Keycloak颁发的JWT令牌中的最新自定义属性?我应该通过传递XML文件来自定义Infinispan配置吗?应该准确更改哪个缓存配置?
- 注意**:一个有帮助的手动解决方法是在Keycloak中使用户的所有用户会话无效。之后,keycloak总是发出具有最新自定义属性的JWT令牌。
FROM <private-/gradle:7.1.0-jdk11 AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon
FROM <private-registry>/quay.io_keycloak/keycloak:19.0.1 as builder
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_DB=postgres
ENV KC_HTTP_RELATIVE_PATH="/auth"
ENV KC_HTTP_ENABLED=true
ENV KC_HOSTNAME_STRICT_HTTPS=false
ENV KC_HOSTNAME_STRICT=false
ENV KC_TRANSACTION_XA_ENABLED=false
ENV KC_SPI_USER_CACHE_DEFAULT_ENABLED=false
COPY --from=build /home/gradle/src/user-storage-spi/build/libs/*.jar /opt/keycloak/providers/
COPY /conf/quarkus.properties /opt/keycloak/conf/quarkus.properties
RUN /opt/keycloak/bin/kc.sh build --spi-user-cache-infinispan-enabled=false
FROM <private-registry>/quay.io_keycloak/keycloak:19.0.1
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak
ENV KC_HTTP_ENABLED=true
ENV KC_HOSTNAME_STRICT_HTTPS=false
ENV KC_HOSTNAME_STRICT=false
ENV KC_TRANSACTION_XA_ENABLED=false
ENV KC_SPI_USER_CACHE_DEFAULT_ENABLED=false
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
1条答案
按热度按时间t2a7ltrp1#
由于凭证输入验证总是在您实现的
UserStorageProvider
中执行,因此您可以使用KeycloakSession
对象简单地使被覆盖的isValid()
方法中的用户无效: