For example, to implement the Theme Selector SPI you need to implement ThemeSelectorProviderFactory and ThemeSelectorProvider and also provide the file
As mentioned above, it is recommended that your `ProviderFactory` implementations use unique ID. However at the same time, it can be useful to override one of the {project_name} built-in providers.
The recommended way for this is still ProviderFactory implementation with unique ID and then for instance set the default provider as
specified in the link:https://www.keycloak.org/server/configuration-provider[Configuring Providers] {section}. On the other hand, this may not be always possible.
For instance when you need some customizations to default OpenID Connect protocol behaviour and you want to override
default {project_name} implementation of `OIDCLoginProtocolFactory` you need to preserve same providerId. As for example admin console, OIDC protocol well-known endpoint and various other things rely on
the ID of the protocol factory being `openid-connect`.
For this case, it is highly recommended to implement method `order()` of your custom implementation and make sure that it has higher order than the built-in implementation.
[source,java]
----
public class CustomOIDCLoginProtocolFactory extends OIDCLoginProtocolFactory {
// Some customizations here
@Override
public int order() {
return 1;
}
}
----
In case of multiple implementations with same provider ID, only the one with highest order will be used by {project_name} runtime.
Sometimes it is useful to show additional info about your Provider to a {project_name} administrator. You can show provider build time information (for example, version of
custom provider currently installed), current configuration of the provider (e.g. url of remote system your provider talks to) or some operational info
(average time of response from remote system your provider talks to). {project_name} Admin Console provides Server Info page to show this kind of information.
For example `HostnameProvider` specifies the hostname to be used by {project_name} and that is shared for the whole {project_name} server.
Hence there can be only single implementation of this provider active for the {project_name} server. If there are multiple provider implementations available to the server runtime,
The value `default` used as the value of `default-provider` must match the ID returned by the `ProviderFactory.getId()` of the particular provider factory implementation.
In the code, you can obtain the provider such as `keycloakSession.getProvider(HostnameProvider.class)`
* *Multiple implementation provider types* - Those are provider types, that allow multiple implementations available and working together
that particular event can be sent to all the listeners (jboss-logging, sysout etc). In the code, you can obtain a specified instance of the provider
for example such as `session.getProvider(EventListener.class, "jboss-logging")` . You need to specify `provider_id` of the provider as the second argument
particular provider factory implementation. Some provider types can be retrieved with the usage of `ComponentModel` as the second argument and some (for example `Authenticator`) even
need to be retrieved with the usage of `KeycloakSessionFactory`. It is not recommended to implement your own providers this way as it may be deprecated in the future.
Provider JARs are not loaded in isolated classloaders, so do not include resources or classes in your provider JARs that conflict with built-in resources or classes.
In particular the inclusion of an application.properties file or overriding the commons-lang3 dependency will cause auto-build to fail if the provider JAR is removed.
If you have included conflicting classes, you may see a split package warning in the start log for the server. Unfortunately not all built-in lib jars are checked by the split package warning logic,
so you'll need to check the lib directory JARs before bundling or including a transitive dependency. Should there be a conflict, that can be resolved by removing or repackaging the offending classes.
There is no warning if you have conflicting resource files. You should either ensure that your JAR's resource files have path names that contain something unique to that provider,
If you find that your server will not start due to a `NoSuchFileException` error related to a removed provider JAR, then run:
[source,bash]
----
./kc.sh -Dquarkus.launch.rebuild=true
----
This will force Quarkus to rebuild the classloading related index files. From there you should be able to perform a non-optimized start or build without an exception.
the current `UserModel`. Note that `user` is available when your script authenticator is configured in the authentication flow in a way that is triggered after
another authenticator succeeded in establishing user identity and set the user into the authentication session.
A possible use of script authenticator is to do some checks at the end of the authentication. Note that if you want
your script authenticator to be always triggered (even for instance during SSO re-authentication with the identity cookie), you may need to add it as REQUIRED at the end
of the authentication flow and encapsulate the existing authenticators into a separate REQUIRED authentication subflow. This need is because the REQUIRED and ALTERNATIVE executions
should not be at the same level. For example, the authentication flow configuration should appear as follows:
NOTE: JAR files are regular ZIP files with a `.jar` extension.
In order to make your scripts available to {project_name} you need to deploy them to the server. For that, you should create
a `JAR` file with the following structure:
[source]
----
META-INF/keycloak-scripts.json
my-script-authenticator.js
my-script-policy.js
my-script-mapper.js
----
The `META-INF/keycloak-scripts.json` is a file descriptor that provides metadata information about the scripts you want to deploy. It is a JSON file with the following structure:
For each script file in your `JAR` file, you need a corresponding entry in `META-INF/keycloak-scripts.json` that maps your scripts files to a specific provider type. For that you should provide the following properties for each entry:
Once you have a JAR file with a descriptor and the scripts you want to deploy, you just need to copy the JAR to the {project_name} `providers/` directory, then run `bin/kc.[sh|bat] build`.
If you want to see list of all available SPIs at runtime, you can check `Server Info` page in Admin Console as described in <<_providers_admin_console,Admin Console>> section.