On 29/04/16 09:43, Marek Posolda wrote:
Yes, AFAIK we have open JIRA for this for a long time ago.
It's the same issue for IdentityProvider (and maybe some others SPI
too) that they bypass "official" way for create provider via
session.getProvider(providerClazz) and hence they are not registered
in KeycloakSession and "close" method is not called for them.
The issue is that our SPI is a bit limited IMO and doesn't support
"stateful" providers. The providers are created through
"ProviderFactory.create(KeycloakSession)". So the only available state
of provider ATM is just ProviderFactory + KeycloakSession, which is
sometimes not sufficient.
I can see 2 possibilities to address:
1) Always make the provider implementation "stateless" and ensure all
the state is passed as argument to provider methods. This is what we
already do for some providers (for example all methods of UserProvider
has RealmModel as parameter). So if we rewrite UserFederation SPI that
UserFederationProviderModel will be passed as argument to all methods
of UserFederationProvider, then it can use "official" way too.
2) Improve the SPI, so it can properly support "stateful" providers.
This is more flexible then (1) and I would go this way long term.
I am thinking about something like this:
public interface StatefulProvider<S> extends Provider {
}
public class StatefulProviderFactory<T extends StatefulProvider, S> {
T create(KeycloakSession session, S state);
.......
}
and on KEycloakSession new method like this:
<S,T extends StatefulProvider<S>>T getProvider(Class<T> providerClazz,
String id,S state);
The "state" will need to properly implement equals and hashCode, so
the SPI can deal with it and not create another instance of
StatefulProvider if it was called for this KeycloakSession with same
state before.
Just adding the example how easily it will work for UserFederation .
The
state will be UserFederationProviderModel, so it will be like:
UserFederationProviderModel providerModel1 = .... // get somehow from DB
UserFederationProviderModel providerModel2 = .... // get somehow from DB
UserFederationProvider ldap1 =
session.getProvider(UserFederationProvider.class, "ldap", providerModel1);
UserFederationProvider ldap2 =
session.getProvider(UserFederationProvider.class, "ldap",
providerModel2); // Will return different instance then "ldap1" as it's
different state (providerModel) used
UserFederationProvider ldap3 =
session.getProvider(UserFederationProvider.class, "ldap",
providerModel1); // Will return existing "ldap1" as it was already used
in this KeycloakSession with this state
At the end of session are 2 registered LDAP providers properly closed.
Marek
Marek
On 29/04/16 08:00, Stian Thorgersen wrote:
> Looking at the code for user federation it looks like user federation
> provider instances with the same configuration can be created
> multiple times for a single session. Also they are never closed to
> resources aren't released.
>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/keycloak-dev
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev