Replies: 23 comments 66 replies
-
@edewit This sounds fantastic ! But how would the actual content of the page be defined ? Through .ftl ? |
Beta Was this translation helpful? Give feedback.
-
@edewit I like the idea to have UI configuration possibilities on the server side. This way, it's easily possible to enable or disable custom UI pages per realm (or have other configuration defined by Admins). However, why not also supporting custom elements without server-side configuration possibilities, i.e. making the server-side SPI optional? For simple extensions, implementing a SPI might be unnecessary effort. That's how I think building extensions could be further simplified. But, of course, I'm not that much into the details. |
Beta Was this translation helpful? Give feedback.
-
@edewit this seems to be an approach to provide screens for configuration data stored as realm attributes, right? Or would it also work for custom screens which work on existing Keycloak data? Let's say if someone wants to
This would not be solved by this approach, I assume. |
Beta Was this translation helpful? Give feedback.
-
Added Draft PR for the quickstart with an example for realm attributes and a todo list section: |
Beta Was this translation helpful? Give feedback.
-
I would like to link to an alternative/additional idea for Admin Console extensions: The admin console doesn't integrate custom UIs but provides convenient navigation to add-on applications, which could be developed and operated independently. See #27738 "Extending the Keycloak Admin Console with links to add-on applications" |
Beta Was this translation helpful? Give feedback.
-
@edewit I am just playing around with the SPI a bit. Great work, thanks for that. I have two questions for now and maybe you can help here:
With reference to my first question and while I think that using the components API to automatically store the configuration is great, are there any plans to make the component accesible that is referenced by the path (like the concrete identity provider config in my example)? |
Beta Was this translation helpful? Give feedback.
-
@edewit I finally had some time to play around with the feature. I am really liking it, because it offers a simple solution to add some customization to the admin ui. Is there any timeline when we can expect this feature to leave the Two things I can add:
To my understanding in the create you should move the persisted values to the model and implement a @Override
public void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) {
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
config.put("logo", List.of(realm.getAttribute("logo")));
model.setConfig(config);
}
@Override
public void onUpdate(KeycloakSession session, RealmModel realm, ComponentModel model, ComponentModel newModel) {
realm.setAttribute("logo", newModel.get("logo"));
} Is this correct?
|
Beta Was this translation helpful? Give feedback.
-
@edewit Thanks for this. I've just started to play with it, and I like the direction it is going. I was experimenting with it to build an admin UI for the webhooks functionality in my events extension. I currently have my own entities to store the properties of the webhooks in the database. So I was able to use the
|
Beta Was this translation helpful? Give feedback.
-
One suggestion for the UI would be to allow placing the left nav link in either the "Manage", "Configure" or optionally an "Extension" section (in order to make it clear to the user that they are using functionality outside of core Keycloak). |
Beta Was this translation helpful? Give feedback.
-
Another issue that came up when testing this is that everything requires
Would be nice to figure out a way to allow such permissions, and not to require an admin user to have full permissions. |
Beta Was this translation helpful? Give feedback.
-
FYI added an enhancement issue here #28931 where I will track the suggested PR. |
Beta Was this translation helpful? Give feedback.
-
We tried the feature to add a tab to the user details. Our goal is allowing the selection of predefined values to be added as attributes to the selected user.
|
Beta Was this translation helpful? Give feedback.
-
I'm working on a PoC using the new Java API (
Should be possible to do 3-5 by adding some methods to String getTitle(ComponentModel component); //use this for title and clickable field
String[] getDisplayOrder(List<ProviderConfigProperty> props); //use this for which fields to show, and in what order |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
How can you prevent default save to the ComponentModel and initialize it from another source? Right now, it seems it always saves to some global component model instance (if it has the same provider id) and reads from it. Likely because it adds a single global "reused" model with that id that is shared regardless of where it is shown. Can we get some method override to prevent it from actually saving anything to the model (overriding onCreate, onUpdate does not work - they trigger after save). |
Beta Was this translation helpful? Give feedback.
-
Hello, I'm using version 25.0.2 and adding feature declarative ui that way and apparently the feature is enabled but my page still doesn't appear. What am I missing? |
Beta Was this translation helpful? Give feedback.
-
First of all, cool idea @edewit! Just spent some time to play around. As far as I understand its currently only possible to add a new UiPage or a UiTab, to an already existing page/tab group. What I would like to do is:
Is this already somehow possible or planned in the future? |
Beta Was this translation helpful? Give feedback.
-
Hello sirs/madams, Please kindly refer to my issue report here. |
Beta Was this translation helpful? Give feedback.
-
I read the whole discussion, but I didn't find an issue for the situation itself. Basically, the CustomTab data needs to be related to the ClientId (UUID), instead of the realm context. I tried to save it directly in the ClientModel attributes, but since I don't have much experience with customizing Keycloak interfaces, I can't persist the information (and I don't even know how to do it, if anyone wants to help me with that). import org.keycloak.Config;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
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;
public class ClientSmtpUITab implements UiTabProvider, UiTabProviderFactory<ComponentModel> {
private KeycloakSession session;
@Override
public String getId() {
return "smtp-config";
}
@Override
public String getPath() {
return "/:realm/clients/:clientId/:tab?";
}
@Override
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("tab", "smtp-config");
return params;
}
@Override
public String getHelpText() {
return "";
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
final ProviderConfigurationBuilder builder = ProviderConfigurationBuilder.create();
builder.property()
.name("smtpHost")
.label("SMTP Host")
.type(ProviderConfigProperty.STRING_TYPE)
.required(false)
.add()
.property()
.name("smtpPort")
.label("SMTP Port")
.type(ProviderConfigProperty.STRING_TYPE)
.required(false)
.add()
.property()
.name("smtpFrom")
.label("SMTP From")
.type(ProviderConfigProperty.STRING_TYPE)
.required(false)
.add()
.property()
.name("smtpDisplayName")
.label("SMTP Display Name")
.type(ProviderConfigProperty.STRING_TYPE)
.required(false)
.add()
.property()
.name("smtpUser")
.label("SMTP User")
.type(ProviderConfigProperty.STRING_TYPE)
.required(false)
.add()
.property()
.name("smtpPassword")
.label("SMTP Password")
.type(ProviderConfigProperty.PASSWORD)
.required(false)
.add()
.property()
.name("smtpAuth")
.label("Enable Authentication")
.type(ProviderConfigProperty.BOOLEAN_TYPE)
.defaultValue(false)
.add()
.property()
.name("smtpSsl")
.label("Enable SSL")
.type(ProviderConfigProperty.BOOLEAN_TYPE)
.required(false)
.add()
.property()
.name("smtpTls")
.label("SMTP Enable StartTLS")
.type(ProviderConfigProperty.BOOLEAN_TYPE)
.required(false)
.add();
return builder.build();
}
@Override
public void init(Config.Scope scope) {
}
@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
}
@Override
public void close() {
}
} |
Beta Was this translation helpful? Give feedback.
-
Hi all, can someone help me? |
Beta Was this translation helpful? Give feedback.
-
I am experiencing an issue with my implementation of the ThemeUiTab class. The implementation works correctly when updating the realm attribute using the administrative interface. However, when I use the REST API to update the realm attribute, the new attribute is saved (as confirmed by checking Keycloak's database), but the input field in the administrative interface still displays the old value. I have tried reloading Keycloak, but the interface does not load the new value from the database. For reference, I implemented the example from the following repository: |
Beta Was this translation helpful? Give feedback.
-
@edewit Where you'd rather have feedback related to this? Here or on a Bug report? I realized, for now, two things:
No idea where it comes from. This is absolutely great. Thanks for the work on this! |
Beta Was this translation helpful? Give feedback.
-
@edewit I have played with it a bit more over the last couple of days, and I wonder if you could think of decoupling the factory from the provider. The thing is that the UiTabProvider and UiTabProviderFactory have a lot of methods in common, but most of them are not called in runtime. I tried adding this to the code, and splittet the Factory and the Provider: @OverRide It feels to me that the Since a lot of people think this could be an awesome way to have an UX for attributes, being able to read the session to update the UX with the current attributes would really be useful here. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Part of how we could do customisation of the UI (#22255), we would like your opinion on introducing an Java API to extend the UI. This UI would be based on things that keycloak already supports, a SPI that you can implement that would force you to return a Configuration that would describe the screen:
Because it's based on the component model you be automatically able to save this information, but we'll add a handler as well so you can have custom logic when the save happens
By adding some json configuration you can choose to have this as a Tab under an existing page or as a "master > detail" page with it's own menu. See #23772 for more details, WDYT?
Beta Was this translation helpful? Give feedback.
All reactions