Fix NPE for component creation when realm unset but config known
Fixes #9019
This commit is contained in:
parent
43c46dbcf8
commit
95614e8b40
3 changed files with 17 additions and 9 deletions
|
@ -306,7 +306,7 @@ public final class KeycloakModelUtils {
|
|||
String componentId = config.get("componentId");
|
||||
if (realmId == null || componentId == null) {
|
||||
realmId = "ROOT";
|
||||
ComponentModel cm = new ScopeComponentModel(providerClass, config, spiName);
|
||||
ComponentModel cm = new ScopeComponentModel(providerClass, config, spiName, realmId);
|
||||
return factory.getProviderFactory(providerClass, realmId, cm.getId(), k -> cm);
|
||||
} else {
|
||||
return factory.getProviderFactory(providerClass, realmId, componentId, componentModelGetter(realmId, componentId));
|
||||
|
@ -318,14 +318,16 @@ public final class KeycloakModelUtils {
|
|||
private final String componentId;
|
||||
private final String providerId;
|
||||
private final String providerType;
|
||||
private final String realmId;
|
||||
private final Scope config;
|
||||
|
||||
public ScopeComponentModel(Class<?> providerClass, Scope baseConfiguration, String spiName) {
|
||||
public ScopeComponentModel(Class<?> providerClass, Scope baseConfiguration, String spiName, String realmId) {
|
||||
final String pr = baseConfiguration.get("provider", Config.getProvider(spiName));
|
||||
|
||||
this.providerId = pr == null ? "default" : pr;
|
||||
this.config = baseConfiguration.scope(this.providerId);
|
||||
this.componentId = spiName + "-" + this.providerId;
|
||||
this.componentId = spiName + "- " + (realmId == null ? "" : "f:" + realmId + ":") + this.providerId;
|
||||
this.realmId = realmId;
|
||||
this.providerType = providerClass.getName();
|
||||
}
|
||||
|
||||
|
@ -349,6 +351,11 @@ public final class KeycloakModelUtils {
|
|||
return componentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentId() {
|
||||
return realmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean get(String key, boolean defaultValue) {
|
||||
return config.getBoolean(key, defaultValue);
|
||||
|
@ -366,7 +373,6 @@ public final class KeycloakModelUtils {
|
|||
|
||||
@Override
|
||||
public String get(String key, String defaultValue) {
|
||||
|
||||
return config.get(key, defaultValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,12 @@ public class DefaultComponentFactoryProviderFactory implements ComponentFactoryP
|
|||
newFactory.init(configScope);
|
||||
newFactory.postInit(factory);
|
||||
|
||||
if (realmId == null) {
|
||||
realmId = configScope.getComponentParentId();
|
||||
}
|
||||
if (realmId != null) {
|
||||
dependentInvalidations.computeIfAbsent(realmId, k -> ConcurrentHashMap.newKeySet()).add(componentId);
|
||||
}
|
||||
dependentInvalidations.computeIfAbsent(newFactory.getClass(), k -> ConcurrentHashMap.newKeySet()).add(componentId);
|
||||
|
||||
return newFactory;
|
||||
|
|
|
@ -354,15 +354,12 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
|||
Integer hash = clazz.hashCode() + componentId.hashCode();
|
||||
T provider = (T) providers.get(hash);
|
||||
final RealmModel realm = getContext().getRealm();
|
||||
if (realm == null) {
|
||||
throw new IllegalArgumentException("Realm not set in the context.");
|
||||
}
|
||||
|
||||
// KEYCLOAK-11890 - Avoid using HashMap.computeIfAbsent() to implement logic in outer if() block below,
|
||||
// since per JDK-8071667 the remapping function should not modify the map during computation. While
|
||||
// allowed on JDK 1.8, attempt of such a modification throws ConcurrentModificationException with JDK 9+
|
||||
if (provider == null) {
|
||||
final String realmId = realm.getId();
|
||||
final String realmId = realm == null ? null : realm.getId();
|
||||
ProviderFactory<T> providerFactory = factory.getProviderFactory(clazz, realmId, componentId, modelGetter);
|
||||
if (providerFactory != null) {
|
||||
provider = providerFactory.create(this);
|
||||
|
|
Loading…
Reference in a new issue