[keycloak-dev] in-memory only federated users

Marek Posolda mposolda at redhat.com
Thu Dec 3 10:32:22 EST 2015


IMO the more important use-case that in-memory federated users is the 
caching of federated users.

Currently if you call: session.users().getUserById() and the user with 
ID "123" is LDAP (or other federationProvider) user, there is always 
call to UserFederationProvider.validateAndProxy , which results in LDAP 
query.

If we introduce the chaining of UserProvider (something I already 
proposed earlier), you can switch UserFederationProvider with cache, so 
you will have:
cache => userFederationManager => JPA

instead of current:

userFederationManager => cache => JPA


With that in mind, we can easily implement in-memory as another 
implementation of UserProvider, which will hold users purely in-memory. 
Our current DefaultCacheUserProvider always require delegate to call 
write operations. But this in-memory provider would be something 
different. It won't use any delegate as it will be in the end of the 
chain. So for in-memory federation you will just configure:

userFederationManager => inMemoryProvider

and you're done. No needs for special ID handling or something like that.

With chaining of UserProvider we have biggest flexibility for various 
needs IMO. That's why I would rather go this way TBH.
Marek

On 02/12/15 17:48, Bill Burke wrote:
> I'm looking into in-memory only no-import federated users.  What we
> would want to do is allow the UserFederationProvider to create an
> in-memory UserModel and allow for that UserModel to be cached via our
> current architecture.
>
> The current design assumes that all federated users are imported.  This
> includes our caching layer too!  To add to that, the user isn't cached
> until the 2nd request i.e.:
>
> 1. username/password page would hit the UserFederationProvider and the
> user would be imported into Keycloak.  This imported user is not cached,
> only imported into the database for this request's KeycloakSession
> 2. OTP Page or code 2 token would then want to lookup the user by id as
> that is what is stored in the ClientSession.  It would hit the keycloak
> database as it is not cached yet.  This lookup loads the cache for the user.
>
> Getting in-memory zero-import to work is even more tricky.  The issue is
> that ClientSession and UserSession need to lookup clients by id.  If the
> user is not in cache, then the cache needs to lookup the user by id
> within storage.  This lookup also needs to happen if a write operation
> is performed on a cache user (getDelegateForUpdate()).  So, Keycloak
> needs to know that that ID is not in local storage and must be looked up
> from a fed provider.  The ID must be formed so that the provider fed
> provider can resolve the lookup.  I could use a URI for the ID i.e.
>
> fed:{providerId}:{login-name}
>
> The problem with this is that this id would need to be larger than 36
> characters which is the current column size for UserEntity.id and any
> other table that references users.   I could possibly do:
>
> fed:{providerAlias}:{login-name}
>
> But its quite possible that combination would be larger than 36
> characters.  We could also just shrink it to:
>
> fed:{login-name}
>
> But then we would have to iterate over every federation provider to find
> and load the user.
>
> So in summary:
> * IDs need to expand from 36 characters to something larger. (255
> maybe).  Don't some DBs have constraints on string primary key size?  DB
> scripts could possibly be
> * CachedUserProvider and UserFederationManager interfaces would need to
> be refactored
> * I don't think UserFederationProvider interface would need to change.
> But users would have to code for in-memory rather than throwing a switch
> to just turn it on.
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-dev/attachments/20151203/69eb17d9/attachment-0001.html 


More information about the keycloak-dev mailing list