Custom UI Tab Incorrectly Displayed Under Multiple Tabs
#38 078 ouverte le 13 mars 2025
Description
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
admin/ui
Describe the bug
When creating a custom UI Tab in the Keycloak Admin Console (Realm settings), the tab incorrectly appears multiple times. Specifically, the newly created tab ("Some Test Tab") is displayed both as a primary tab and also as a nested child under other unrelated tabs such as Keys, Client policies, and User profile. This behavior does not occur consistently across all tabs; for example, the tab does not incorrectly appear under the Security defenses tab even though it also contains child tabs.
Clicking the incorrectly nested "Some Test Tab" redirects to the correct primary tab location.
Version
26.1.3
Regression
- The issue is a regression
Expected behavior
When adding a custom UI Tab, it should only appear at the top level and not as a nested tab under any other tabs.
Actual behavior
The custom tab appears multiple times, incorrectly nested beneath unrelated parent tabs.
How to Reproduce?
Create a new Tab via the TabUiProvider like the example below. Then go to Realm settings or the defined place where the tab should be displayed.
import com.google.auto.service.AutoService;
import lombok.extern.jbosslog.JBossLog;
import org.keycloak.Config;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.services.ui.extend.UiTabProvider;
import org.keycloak.services.ui.extend.UiTabProviderFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@JBossLog
@AutoService(UiTabProviderFactory.class)
public class TestUiTabProvider implements UiTabProvider, UiTabProviderFactory<ComponentModel> {
final public static String NAME = "Some Test Tab";
@Override
public String getPath() {
return "/:realm/realm-settings/:tab?";
}
@Override
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("tab", NAME);
return params;
}
@Override
public String getHelpText() {
return "Some information about the test tab";
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
ProviderConfigurationBuilder builder = ProviderConfigurationBuilder.create();
builder.property()
.name("someCoolInput")
.label("someCoolInput")
.type(ProviderConfigProperty.STRING_TYPE)
.helpText("Information about someCoolInput")
.add();
return builder.build();
}
@Override
public void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) {
// do something
}
@Override
public void onUpdate(KeycloakSession session, RealmModel realm, ComponentModel oldModel, ComponentModel newModel) {
// do something
}
@Override
public void init(Config.Scope scope) {
}
@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
// do something
}
@Override
public void close() {
}
@Override
public String getId() {
return NAME;
}
}
Anything else?
No response