Hi,
I’m currently evaluating migrating our authentication stuff to keycloak.
I already have a bunch of users saved in a database, including their username, salt and hashed password hashed by SHA256.
Now I’m trying to migrate those users into my keycloak instance, because I don’t want them to need to reset their passwords if I do the migration.
I’ve tried this answer to get started with the Java admin client, however I always get a 400 Bad Request
as a response, which I think is because the value
field is empty (although stated as optional in the documentation)
This is what I’ve come up with:
var newCredentials = new CredentialRepresentation();
newCredentials.setTemporary(false);
newCredentials.setType(CredentialRepresentation.PASSWORD);
newCredentials.setSecretData(createSecretJson(salt, hash));
newCredentials.setCredentialData(credateCredentialJson());
var userId = realm.users().search(username, true).get(0).getId();
var user = realm.users().get(userId);
user.resetPassword(newCredentials);
and this is the response:
javax.ws.rs.BadRequestException: HTTP 400 Bad Request
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:219)
at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.DefaultEntityExtractorFactory$3.extractEntity(DefaultEntityExtractorFactory.java:50)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:151)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:112)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy37.resetPassword(Unknown Source)
I also can’t find any indication about the error in the log (using level DEBUG).
Updating the user representation like this:
var newCredentials = new CredentialRepresentation();
newCredentials.setTemporary(false);
newCredentials.setType(CredentialRepresentation.PASSWORD);
newCredentials.setSecretData(createSecretJson(salt, hash));
newCredentials.setCredentialData(credateCredentialJson());
var userId = realm.users().search(username, true).get(0).getId();
var user = realm.users().get(userId);
var userRepresentation = user.toRepresentation();
userRepresentation.setCredentials(List.of(newCredentials));
user.update(userRepresentation);
Does save the credentials, but I’m not able to login (wrong password).
The salt and hash is encoded as Base64 before being sent to the API.
The JSON that gets send for the credential representation is:
{"type":"password","secretData":"{"value":"MWQ3MDc4MTE5ODgwNjljYTc2MDgyNjg2MWQ2ZDYzYTEwZThjM2I3ZjE3MWM0NDQxYTY0NzJlYTU4YzExNzExYg==","salt":"YXNkZmFzZGY="}","credentialData":"{"hashIterations":1,"algorithm":"HS256"}","temporary":false}