[keycloak-user] Best practice for database access in a keycloak custom provider?

Stian Thorgersen sthorger at redhat.com
Fri Oct 9 01:15:04 EDT 2015


One issue with the federation provider is that at least for the time being
you can't deprovision the old store, so you end up with having users in the
Keycloak database as well as your old database. In the long run that'll be
more to maintain. It would be great if we provided a way to deprovision a
federation provider. It would give you an option of either migrate all
users or remove users. Would require either being able to read password
hashes (and also a password hash spi), or if that's not possible users
would not be able to login until they have recovered their password over
email or an admin has recovered their password for them.

On 8 October 2015 at 20:56, Scott Rossillo <srossillo at smartling.com> wrote:

> One plus of the federation provider approach is that it requires zero
> downtime. Users start migrating on login rather than shutting down the
> legacy system, importing users, and bringing things back up.
>
> Scott Rossillo
> Smartling | Senior Software Engineer
> srossillo at smartling.com
>
> [image: Powered by Sigstr] <http://www.sigstr.com/>
>
> On Oct 8, 2015, at 1:49 PM, Stian Thorgersen <sthorger at redhat.com> wrote:
>
> For the database in a user federation provider you can use JpaConnectionProvider,
> but then you have to modify our persistence.xml. Alternatively you can
> create your own EntityManagerFactory within your
> UserFederationProviderFactory. Downside to that is that you won't share the
> connection (and 1pc transaction). We could improve on this in the future as
> it's a bit clunky.
>
> The other alternative is that we plan to introduce a password hashing spi.
> With that you can provide the implementation that can hash passwords
> according to how you have them saved in your current database. Then you can
> import the users directly into Keycloak and forget about the user
> federation provider. To import the users you can either export them from
> your db to a json file (currently you need a full realm file, but we are
> looking at doing partial import/export now and with that you'll be able to
> import a json file with users only into an existing realm). Alternatively
> you can use the rest admin api to import them.
>
> On 8 October 2015 at 10:17, Valerij Timofeev <valerij.timofeev at gmail.com>
> wrote:
>
>> Exactly.
>>
>> Plain text passwords are unknown, so the "custom user federation
>> provider" approach, suggested by Scott Rossillo in the keycloak-user
>> Digest, Vol 22, Issue 18, seems to be feasible:
>> - User federation provider searches for the user in the legacy user
>> storage on the 1st login.
>> - If the user is found and the password legacy hash matches the value in
>> the legacy user storage, user credential is updated in the Keycloak storage
>> and federation link is removed then (see code snippet below).
>>
>> My question is, what would be the best way to access legacy database from
>> within a Keycloak custom provider?
>> JPA datasource  for the legacy database is available on the same
>> application server, where the Keycloak server runs (EAP 6.4.3).
>>
>>
>> @Override
>>
>>     public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input)
>>
>>     {
>>
>>         for (UserCredentialModel cred : input)
>>
>>         {
>>
>>             if (cred.getType().equals(UserCredentialModel.PASSWORD))
>>
>>             {
>>
>>
>>                 return this.updateCredential(realm, user, cred);
>>
>>
>>             } else
>>
>>             {
>>
>>                 return false; // invalid cred type
>>
>>             }
>>
>>         }
>>
>>         return false;
>>
>>     }
>>
>>
>>
>>     private boolean updateCredential(RealmModel realm, UserModel user, UserCredentialModel cred)
>>
>>     {
>>
>>         String password = properties.getProperty(user.getUsername());
>>
>>         if (password == null)
>>
>>             return false;
>>
>>
>>
>>         String encodedPassword = Digest.createPassword(cred.getValue());
>>
>>         boolean isPasswordOK = password.equals(encodedPassword);
>>
>>         if (isPasswordOK)
>>
>>         {
>>
>>             // save password
>>
>>             session.userStorage().getUserById(user.getId(), realm).updateCredential(cred);
>>
>>             // break the federation link
>>
>>             session.userStorage().getUserById(user.getId(), realm).setFederationLink(null);
>>
>>         }
>>
>>         return isPasswordOK;
>>
>>     }
>>
>>
>> 2015-10-08 5:57 GMT+02:00 Stian Thorgersen <sthorger at redhat.com>:
>>
>>> Do you want to permanently import the users into the Keycloak database?
>>>
>>> On 7 October 2015 at 18:37, Valerij Timofeev <valerij.timofeev at gmail.com
>>> > wrote:
>>>
>>>> Hi,
>>>>
>>>> in order to import users having encrypted passwords from existing user
>>>> storage I'm implementing user federation provider based on the
>>>> keycloak example
>>>> *keycloak-examples-1.5.0.Final/providers/federation-provider*
>>>> *.*
>>>> Additionally I considered hints provided by Scott Rossillo in the
>>>> keycloak-user Digest, Vol 22, Issue 18
>>>> Above example works properly when retrieving users from a properties
>>>> file. The next step in the implementation would be access to the database
>>>> where users data is stored.
>>>>
>>>> *My question: *What would be the best practice for accessing database
>>>> from a custom keycloak provider?
>>>>
>>>> Something like this?
>>>>
>>>> // KeycloakSession
>>>> session.getProvider(JpaConnectionProvider.class, "myTS")
>>>>                 .getEntityManager()
>>>>                 .createQuery("SELECT... ?
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> *keycloak-server.json:"connectionsJpa": {        "default":
>>>> {            "dataSource": "java:jboss/datasources/KeycloakDS",
>>>> "databaseSchema": "update"        },*
>>>>
>>>>
>>>>
>>>> *"myTS": {            "dataSource":
>>>> "java:jboss/datasources/myTsDS"        }    }*Thank you,
>>>>
>>>> Valerij Timofeev
>>>> Software Engineer
>>>> Trusted Shops GmbH
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> keycloak-user mailing list
>>>> keycloak-user at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>
>>>
>>>
>>
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-user/attachments/20151009/84ac926e/attachment-0001.html 


More information about the keycloak-user mailing list