[keycloak-dev] User Federation Provider Cache
Bill Burke
bburke at redhat.com
Mon Jun 13 08:56:34 EDT 2016
I'm working on a new SPI right now. Here is my notebad to capture how
things work, issues weed to consider, and problems we have to solve:
https://github.com/keycloak/keycloak/wiki/2.0-User-Federation-Storage-SPI
On 6/13/16 3:39 AM, Marek Posolda wrote:
> We discussed some time ago how to ensure that UserFederationProvider
> lifecycle is properly tight to KeycloakSession
> http://lists.jboss.org/pipermail/keycloak-dev/2016-April/007123.html .
> The last we discussed was to add new method on KeycloakSession like:
>
> <T extends Provider> T getProvider(Class<T> clazz, String id, String
> instanceId);
>
> where instanceId is the state associated with the provider (in case of
> UserFederationProvider it will be DB ID of
> UserFederationProviderModelId). That way, the
> UserFederationProviderFactory.create can load the
> UserFederationProviderModel (assumption is that RealmModel is
> available in KeycloakContext, so UserFederationProviderFactory.create
> has access to RealmModel + providerDatabaseId to load it from DB).
>
> In the thread, you can see that I've initially proposed something
> similar to your proposal, but it's a bit more complex though.
> Hopefully going "simple" way and adding just the method with
> "instanceId" String argument can solve the issue.
>
> Marek
>
> On 10/06/16 01:36, Ariel Carrera wrote:
>> There is not problem! :)
>> One more thing, I solved the problem of multiple "federation
>> provider" instances, adding this code to the DefaultKeycloakSession
>> (and the method definition in KeycloakSession interface):
>>
>> public <T extends Provider> void registerProvider(Class<T> clazz,
>> Provider provider, String id) {
>> Integer hash = clazz.hashCode() + id.hashCode();
>> providers.put(hash, provider);
>> }
>>
>>
>> And into MyUserFederationProviderFactory.getInstance(session, model)
>> something like this:
>>
>> public UserFederationProvider getInstance(KeycloakSession
>> session, UserFederationProviderModel model){
>> UserFederationProvider provider = (UserFederationProvider)
>> session.getProvider(UserFederationProvider.class, model.getId());
>> if (provider == null){
>> lazyInit(session);
>> provider = new MyUserFederationProvider(session, model,
>> config, ......);
>> ((KeycloakSession)session).registerProvider(UserFederationProvider.class,
>> provider, model.getId());
>> };
>> return provider;
>> }
>>
>>
>> After a few tests and debug it seems to work... creating, catching,
>> and closing provider instances as expected.
>>
>>
>> In future versions as you said, maybe would be better include a way
>> to instantiate a complex object/provider instead of doing
>>
>> ProviderFactory.create(KeycloakSession session)
>> some kind of method like
>> ProviderFactory.create(KeycloakSession session, Object... obj);
>>
>> and the appropriate method into the KeycloakSession
>>
>> <T extends Provider> T getProvider(Class<T> clazz, Object... obj);
>> <T extends Provider> T getProvider(Class<T> clazz, String id,
>> Object... obj);
>>
>>
>> And why not a map into the keycloakSession to store some additional
>> context data to share between providers during same request? It's
>> only a vague idea
>>
>> Regards!
>>
>> 2016-06-09 17:14 GMT-03:00 Bill Burke <bburke at redhat.com
>> <mailto:bburke at redhat.com>>:
>>
>> Its gonna be awhile. Its going to be difficult to make
>> everything both backward compatible and cover all the current and
>> future use cases we need to cover. Listen on the dev list. I
>> should post some info soon on what the new impl will look like.
>>
>>
>> On 6/9/16 3:57 PM, Ariel Carrera wrote:
>>> Yes Bill, exactly! I will waiting to test it Thanks!
>>>
>>> 2016-06-09 16:29 GMT-03:00 Bill Burke <bburke at redhat.com>:
>>>
>>>
>>>
>>> On 6/9/16 2:52 PM, Ariel Carrera wrote:
>>>
>>> Hi Bill, is a little expensive for me because I am
>>> creating a new entity manager to connect with a legacy
>>> database, and creating/enlisting a transaction per instance.
>>> For example in a simple flow case where a user needs to
>>> click "I forgot my password" link to recover the
>>> password, there is more than nine or ten instances
>>> created to do this. It's really not a big problem but I
>>> think that is not necessary and can be implemented like
>>> others spi providers catched into the keycloak session.
>>>
>>> This is good feedback. We need a way to associate a
>>> provider, by name, to the KeycloakSession. Maybe we just
>>> need a way to associate anything with the KeycloakSession
>>> period.
>>>
>>> In my case, another difficulty is synchronization
>>> between an old authentication system and keycloak
>>> implemented on demand (there is no full/partial
>>> syncrhonization because the legacy system is still
>>> working and need to work together for a while). Also I
>>> implemented synchronization support but at this moment
>>> it not used.
>>> Every time that keycloak needs to validate a user
>>> (isValid) recovered from the user storage or cache, a
>>> query to the legacy system is made. Added to this... I
>>> need to recover some attributes and roles changes
>>> produced on the legacy system.... so I decided to
>>> implement a "user federation cache" with a short term
>>> expiration to improve the performance with certain
>>> synchronization delay tolerance.
>>>
>>> In a few words I have: a custom User Federation Provider
>>> + on deman synchronization + a user Federation Provider
>>> Cache (my own cache SPI).
>>>
>>> Maybe an optional spi to obtain a custom container from
>>> infinispan could be a good choice to add to the new
>>> implementation and provide another one tool to do things
>>> with better performance.
>>>
>>> I think the new model might solve your caching needs. There
>>> will be no importing by default. This means no synching,
>>> etc. Keycloak will only store metadata that your user store
>>> can't provide. User Federation Providers will work just as
>>> the default Keycloak user store and user cache.
>>>
>>>
>>>
>>>
>>> --
>>> Tatú
>>
>>
>>
>>
>> --
>> Tatú
>>
>>
>> _______________________________________________
>> keycloak-dev mailing list
>> keycloak-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>
>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-dev/attachments/20160613/988933b8/attachment.html
More information about the keycloak-dev
mailing list