Avoid holding on to the realm in cached configurations

Closes #43744

Signed-off-by: Alexander Schwartz <alexander.schwartz@ibm.com>
This commit is contained in:
Alexander Schwartz 2025-10-29 12:01:02 +01:00 committed by GitHub
parent 8f8dabab55
commit 4cd381edbf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 22 additions and 37 deletions

View File

@ -727,13 +727,13 @@ public class RealmAdapter implements CachedRealmModel {
@Override
public CibaConfig getCibaPolicy() {
if (isUpdated()) return updated.getCibaPolicy();
return cached.getCibaConfig(session, modelSupplier);
return cached.getCibaConfig(modelSupplier);
}
@Override
public ParConfig getParPolicy() {
if (isUpdated()) return updated.getParPolicy();
return cached.getParConfig(session, modelSupplier);
return cached.getParConfig(modelSupplier);
}
@Override

View File

@ -112,8 +112,6 @@ public class CachedRealm extends AbstractExtendableRevisioned {
protected int accessCodeLifespanUserAction;
protected int accessCodeLifespanLogin;
protected LazyLoader<RealmModel, OAuth2DeviceConfig> deviceConfig;
protected LazyLoader<RealmModel, CibaConfig> cibaConfig;
protected LazyLoader<RealmModel, ParConfig> parConfig;
protected int actionTokenGeneratedByAdminLifespan;
protected int actionTokenGeneratedByUserLifespan;
protected int notBefore;
@ -229,8 +227,6 @@ public class CachedRealm extends AbstractExtendableRevisioned {
accessTokenLifespanForImplicitFlow = model.getAccessTokenLifespanForImplicitFlow();
accessCodeLifespan = model.getAccessCodeLifespan();
deviceConfig = new DefaultLazyLoader<>(OAuth2DeviceConfig::new, null);
cibaConfig = new DefaultLazyLoader<>(CibaConfig::new, null);
parConfig = new DefaultLazyLoader<>(ParConfig::new, null);
accessCodeLifespanUserAction = model.getAccessCodeLifespanUserAction();
accessCodeLifespanLogin = model.getAccessCodeLifespanLogin();
actionTokenGeneratedByAdminLifespan = model.getActionTokenGeneratedByAdminLifespan();
@ -531,12 +527,12 @@ public class CachedRealm extends AbstractExtendableRevisioned {
return deviceConfig.get(session, modelSupplier);
}
public CibaConfig getCibaConfig(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
return cibaConfig.get(session, modelSupplier);
public CibaConfig getCibaConfig(Supplier<RealmModel> modelSupplier) {
return new CibaConfig(modelSupplier.get());
}
public ParConfig getParConfig(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
return parConfig.get(session, modelSupplier);
public ParConfig getParConfig(Supplier<RealmModel> modelSupplier) {
return new ParConfig(modelSupplier.get());
}
public int getActionTokenGeneratedByAdminLifespan() {

View File

@ -21,6 +21,7 @@ import java.util.function.Supplier;
public abstract class AbstractConfig implements Serializable {
@Deprecated(since = "26.5", forRemoval = true)
protected transient Supplier<RealmModel> realm;
// Make sure setters are not called when calling this from constructor to avoid DB updates

View File

@ -42,10 +42,10 @@ public class CibaConfig extends AbstractConfig {
public static final int DEFAULT_CIBA_POLICY_INTERVAL = 5;
public static final String DEFAULT_CIBA_POLICY_AUTH_REQUESTED_USER_HINT = "login_hint";
private String backchannelTokenDeliveryMode = DEFAULT_CIBA_POLICY_TOKEN_DELIVERY_MODE;
private int expiresIn = DEFAULT_CIBA_POLICY_EXPIRES_IN;
private int poolingInterval = DEFAULT_CIBA_POLICY_INTERVAL;
private String authRequestedUserHint = DEFAULT_CIBA_POLICY_AUTH_REQUESTED_USER_HINT;
private String backchannelTokenDeliveryMode;
private int expiresIn;
private int poolingInterval;
private String authRequestedUserHint;
// client attribute names
public static final String OIDC_CIBA_GRANT_ENABLED = "oidc.ciba.grant.enabled";
@ -54,24 +54,20 @@ public class CibaConfig extends AbstractConfig {
public static final String CIBA_BACKCHANNEL_AUTH_REQUEST_SIGNING_ALG = "ciba.backchannel.auth.request.signing.alg";
public CibaConfig(RealmModel realm) {
this.realm = () -> realm;
setBackchannelTokenDeliveryMode(realm.getAttribute(CIBA_BACKCHANNEL_TOKEN_DELIVERY_MODE));
String expiresIn = realm.getAttribute(CIBA_EXPIRES_IN);
if (StringUtil.isNotBlank(expiresIn)) {
setExpiresIn(Integer.parseInt(expiresIn));
this.backchannelTokenDeliveryMode = realm.getAttribute(CIBA_BACKCHANNEL_TOKEN_DELIVERY_MODE);
if (this.backchannelTokenDeliveryMode == null) {
this.backchannelTokenDeliveryMode = DEFAULT_CIBA_POLICY_TOKEN_DELIVERY_MODE;
}
String interval = realm.getAttribute(CIBA_INTERVAL);
this.expiresIn = realm.getAttribute(CIBA_EXPIRES_IN, DEFAULT_CIBA_POLICY_EXPIRES_IN);
if (StringUtil.isNotBlank(interval)) {
setPoolingInterval(Integer.parseInt(interval));
this.poolingInterval = realm.getAttribute(CIBA_INTERVAL, DEFAULT_CIBA_POLICY_INTERVAL);
this.authRequestedUserHint = realm.getAttribute(CIBA_AUTH_REQUESTED_USER_HINT);
if (authRequestedUserHint == null) {
authRequestedUserHint = DEFAULT_CIBA_POLICY_AUTH_REQUESTED_USER_HINT;
}
setAuthRequestedUserHint(realm.getAttribute(CIBA_AUTH_REQUESTED_USER_HINT));
this.realmForWrite = () -> realm;
}

View File

@ -16,8 +16,6 @@
*/
package org.keycloak.models;
import org.keycloak.utils.StringUtil;
public class ParConfig extends AbstractConfig {
// realm attribute names
@ -26,19 +24,13 @@ public class ParConfig extends AbstractConfig {
// default value
public static final int DEFAULT_PAR_REQUEST_URI_LIFESPAN = 60; // sec
private int requestUriLifespan = DEFAULT_PAR_REQUEST_URI_LIFESPAN;
private int requestUriLifespan;
// client attribute names
public static final String REQUIRE_PUSHED_AUTHORIZATION_REQUESTS = "require.pushed.authorization.requests";
public ParConfig(RealmModel realm) {
this.realm = () -> realm;
String requestUriLifespan = realm.getAttribute(PAR_REQUEST_URI_LIFESPAN);
if (StringUtil.isNotBlank(requestUriLifespan)) {
setRequestUriLifespan(Integer.parseInt(requestUriLifespan));
}
this.requestUriLifespan = realm.getAttribute(PAR_REQUEST_URI_LIFESPAN, DEFAULT_PAR_REQUEST_URI_LIFESPAN);
this.realmForWrite = () -> realm;
}