[keycloak-dev] How would you handle an external user store?
Marek Posolda
mposolda at redhat.com
Tue Jul 8 16:06:19 EDT 2014
On 8.7.2014 18:50, Bill Burke wrote:
>> AuthProvider is trying to achieve something different than storing users, and the combination of the two is quite flexible.
> They serve different purposes? And yet AuthProvider stores users:
>
> AuthProvider.registerUser()
>
> and retrieves them:
>
> AuthProvider.getUser()
>
> Then you have AuthenticationManager which creates a UserModel, sets up
> an AuthenticationLink. So a developer has to implement registerUser()
> as well as the create interfaces of UserProvider.
IMO the difference is:
- UserProvider is used to implement whole storage SPI and store *all*
informations needed for user (roles, socialLinks, requiredRoles etc...)
- AuthenticationProvider is used just for password based authentication
and hence need just very small subset of UserProvider methods. Note that
methods "registerUser" and "updatePassword" are not mandatory to
implement if you set "passwordUpdateSupported" for particular
AuthenticationProvider to false. Method "registerUser" is used just to
send "some" data of UserModel to the Auth store, but it doesn't need to
be all (For example with LDAP you store just username, firstName,
lastName, email ).
The point is, that AuthenticationProvider is really easy to implement as
it doesn't need to store all Keycloak data related to user. See
PropertiesAuthenticationProvider from our examples. And note that we
already have community members, who implement their own Authentication
providers. IMO LDAP, Properties file, or legacy database are classic
example, which suits much better as AuthenticationProvider than
UserProvider.
I am not sure if Federation based on metadata on UserModel is good idea.
I think we already discussed Federation approach and the decision was to
avoid it due to many reasons. I believe that Authentication SPI and Sync
SPI were introduced mainly to avoid federation approach...
I am happy with AuthUserProvider, which delegates "store" to other
underlying UserProvider, but authentication to one or more
AuthenticationProviders. This might help to remove the "authentication"
related code from AuthenticationManager. So something like:
+--------------------+
Store | |
+------------> JpaUserProvider |
| | |
| +--------------------+
+------------------+
| |
| AuthUserProvider | +--------------------+
| | | |
+------------------+ | LDAPAuthenticationProvider |
+------------> |
Authenticate +--------------------+
LDAPUserProvider or PropertiesFileUserProvider doesn't make much sense
to me as implementors would need to leave almost all methods empty or
"throw new NotImplementedException()"
>
> More often than not, authentication and user storage will be from the
> same place, then you have to doubly configure the LDAP connection for
> both the UserProvider and the AuthProvider. Except one is configured in
> the Admin Console (AuthProvider) and the other within keycloak-server.json.
I don't think so. AuthenticationProvider is used mainly for case when
you don't have both authentication and user storage in same place. With
AuthUserProvider Stian proposed, we might have AuthUserProvider to be
used in cases when user configured some AuthenticationProviders.
Otherwise directly use JpaUserProvider to store everything (including
authentication) and completely skip AuthenticationProvider layer in this
case.
As I said LDAPUserProvider doesn't make much sense to me, so it's not
needed to configure in 2 places. AFAIK in next KC version, the plan for
stuff like SMTP and LDAP is to remove it from realm configuration and
move it to keycloak-server.json . And also the possibility to configure
stuff from keycloak-server.json in admin console UI.
Marek
More information about the keycloak-dev
mailing list