18 2.0 User Federation Storage SPI
Bill Burke edited this page 2016-06-20 16:37:58 -04:00
  • Must support no-import
  • Make SPI simpler
  • Plan on using an URN for User, Group, and Role IDs i.e.
    • uuid | 'f:' + user-provider-uuid + ':' + opaque-user-id
    • a plain uuid is for backward compatibility
    • This URN should not leak information as it will be included in claims/assertions. Maybe have it be a JWE?
  • Deprecate User Federation SPI? Or remove it entirely? (My current thought is to deprecate. Implementation will shed light on this)
  • How to handle export/import?
  • Do we want to be able to define cache policies per provider?
    • this might be really useful for different providers. Local provider may have really long cache times. An LDAP server might have short ones for
    • Maybe "evictUserOnLogout" switch?
  • Need to be able to tie a provider to a KeycloakSession as they can be expensive to create. Maybe a getInstance() method on KeycloakSession. provider would be created, automatically registered with session, re-used automatically, and closed at end of session
  • Since we are unifying SPIs here, we have to be careful about import/export. For export, we have to have a flag on the provider whether to export it or not. Backwards compatibility of export model will be a pain too.
  • https://issues.jboss.org/browse/KEYCLOAK-1075 Transaction support for resources need to be built in. Maybe have an addUser(RealmModel realm, UserEntity user) method?

Single User Federated Storage

This is when data for a single user is spread out into multiple stores. An external store may not support all the features of Keycloak, so additional data may be stored locally

  • No imports. Only create metadata when needed.
  • If user is being augmented locally, then only store what is needed. No need to "import" the user like we currently do. This is why we use an URN for User IDs.
  • How to handle default roles/groups?
    • Option to create default role/group mappings locally?
    • Option to apply current default roles/groups?
  • How to handle overrides? i.e. a read-only store and we want to update password

Transient Users

Transient users are users that are not backed by storage and thus can't be queried out of band.

  • Brokered Logins No Import
    • Store info in user session?
  • Brokered Logins should still allow import
    • What's nice about this is that brokered logins don't effect user storage SPI.
  • Kerberos SPNEGO
    • Kerberos validates token pulls username from it.
    • Currently Imports user if it doesn't already exist. Removes old user if kerberos principals don't match
  • Client Cert may be similar to Kerberos
  • How to handle default roles/groups?
  • How to handle in cluster?
    • Tie them to a user session?
  • Account Service?
    • User will be logged in, so this will work.
  • Offline tokens?
    • Maybe mark users as transient Offline tokens don't work with transient users?
    • Have switch to allow offline tokens to work with transient users?
    • Import user into offline token storage if it is transient?
  • Do we allow an import option for transient user stores?

Transient Roles/Groups

Transient roles/groups are roles and groups identified when a user is queried. For example, currently for LDAP we import roles on the fly into our database. I want investigate whether this is something that is feasible to implement.

  • How to create protocol mappers for these roles/groups?
  • How to manage role mappings as there is no way to list available roles to apply?

JPA model vs. Adapter model

JPA Model is where we will have a generic UserEntity class which will hold state and we will provide a UserAdapter implementation that manages this in-memory object. The providers will receive this entity at transaction commit time and will determine if and what updates have happened and execute them.

  • Nice because provider doesn't have to implement UserModel interface or know about the federated store when loading users. For a lot of stores Keycloak will just be a passthrough and will not perform updates.
  • For updates, provider will still have to coordinate with federated storage.
  • Can't figure out how to handle credential updates as password histories have to be maintained if Keycloak is managing passwords.
  • Can't figure out how to implement getCredentialsDirectly() after an update. updateCredential may add history and a password credential type.

Adapter model is that the provider implements its own UserAdapter and is responsible for coordinating with federated storage.

  • More control fine grain control over things. Might provide a more flexible way of doing things.
  • providers have to implement full UserModel interface. Maybe not such a big deal?