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(a)smartling.com
<
On Oct 8, 2015, at 1:49 PM, Stian Thorgersen
<sthorger(a)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(a)gmail.com
<mailto:valerij.timofeev@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(a)redhat.com
<mailto:sthorger@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(a)gmail.com
<mailto:valerij.timofeev@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(a)lists.jboss.org <mailto:keycloak-user@lists.jboss.org>
https://lists.jboss.org/mailman/listinfo/keycloak-user
<
https://lists.jboss.org/mailman/listinfo/keycloak-user>
_______________________________________________
keycloak-user mailing list
keycloak-user(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user