On 12/02/2015 11:48 AM, 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}
I'd recommend this, and increasing the size of the Database column.
Keystoen did this, but then SHA256 hashed it, makuing it a 64 character
string. We found we were OK so long as we stayed under 255, as that was
the limit mysql imposed for the string columns.
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.
It gets trickier: you don;'t want one federation provider to step on
the login from an other: ayoung@coke is a different user from
ayoung@pepsi. Having the Id be something issued by Keycloak + something
that comes from the Federated IdP is necessary.
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
255 is your limit.
* 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.
I like in memory, but there are many questions to answer, when a user
comes back a second time, what happens with their Id. I pushed for
ephemeral for Keystone, and we couldn't make it work.