-
-
Save thomasdarimont/c4e739c5a319cf78a4cff3b87173a84b to your computer and use it in GitHub Desktop.
package demo.plain; | |
import org.keycloak.OAuth2Constants; | |
import org.keycloak.admin.client.CreatedResponseUtil; | |
import org.keycloak.admin.client.Keycloak; | |
import org.keycloak.admin.client.KeycloakBuilder; | |
import org.keycloak.admin.client.resource.RealmResource; | |
import org.keycloak.admin.client.resource.UserResource; | |
import org.keycloak.admin.client.resource.UsersResource; | |
import org.keycloak.representations.idm.ClientRepresentation; | |
import org.keycloak.representations.idm.CredentialRepresentation; | |
import org.keycloak.representations.idm.RoleRepresentation; | |
import org.keycloak.representations.idm.UserRepresentation; | |
import javax.ws.rs.core.Response; | |
import java.util.Arrays; | |
import java.util.Collections; | |
public class KeycloakAdminClientExample { | |
public static void main(String[] args) { | |
String serverUrl = "http://sso.tdlabs.local:8899/u/auth"; | |
String realm = "acme"; | |
// idm-client needs to allow "Direct Access Grants: Resource Owner Password Credentials Grant" | |
String clientId = "idm-client"; | |
String clientSecret = "0d61686d-57fc-4048-b052-4ce74978c468"; | |
// // Client "idm-client" needs service-account with at least "manage-users, view-clients, view-realm, view-users" roles for "realm-management" | |
// Keycloak keycloak = KeycloakBuilder.builder() // | |
// .serverUrl(serverUrl) // | |
// .realm(realm) // | |
// .grantType(OAuth2Constants.CLIENT_CREDENTIALS) // | |
// .clientId(clientId) // | |
// .clientSecret(clientSecret).build(); | |
// User "idm-admin" needs at least "manage-users, view-clients, view-realm, view-users" roles for "realm-management" | |
Keycloak keycloak = KeycloakBuilder.builder() // | |
.serverUrl(serverUrl) // | |
.realm(realm) // | |
.grantType(OAuth2Constants.PASSWORD) // | |
.clientId(clientId) // | |
.clientSecret(clientSecret) // | |
.username("idm-admin") // | |
.password("admin") // | |
.build(); | |
// Define user | |
UserRepresentation user = new UserRepresentation(); | |
user.setEnabled(true); | |
user.setUsername("tester1"); | |
user.setFirstName("First"); | |
user.setLastName("Last"); | |
user.setEmail("tom+tester1@tdlabs.local"); | |
user.setAttributes(Collections.singletonMap("origin", Arrays.asList("demo"))); | |
// Get realm | |
RealmResource realmResource = keycloak.realm(realm); | |
UsersResource usersRessource = realmResource.users(); | |
// Create user (requires manage-users role) | |
Response response = usersRessource.create(user); | |
System.out.printf("Repsonse: %s %s%n", response.getStatus(), response.getStatusInfo()); | |
System.out.println(response.getLocation()); | |
String userId = CreatedResponseUtil.getCreatedId(response); | |
System.out.printf("User created with userId: %s%n", userId); | |
// Define password credential | |
CredentialRepresentation passwordCred = new CredentialRepresentation(); | |
passwordCred.setTemporary(false); | |
passwordCred.setType(CredentialRepresentation.PASSWORD); | |
passwordCred.setValue("test"); | |
UserResource userResource = usersRessource.get(userId); | |
// Set password credential | |
userResource.resetPassword(passwordCred); | |
// // Get realm role "tester" (requires view-realm role) | |
RoleRepresentation testerRealmRole = realmResource.roles()// | |
.get("tester").toRepresentation(); | |
// | |
// // Assign realm role tester to user | |
userResource.roles().realmLevel() // | |
.add(Arrays.asList(testerRealmRole)); | |
// | |
// // Get client | |
ClientRepresentation app1Client = realmResource.clients() // | |
.findByClientId("app-frontend-springboot").get(0); | |
// | |
// // Get client level role (requires view-clients role) | |
RoleRepresentation userClientRole = realmResource.clients().get(app1Client.getId()) // | |
.roles().get("user").toRepresentation(); | |
// | |
// // Assign client level role to user | |
userResource.roles() // | |
.clientLevel(app1Client.getId()).add(Arrays.asList(userClientRole)); | |
// Send password reset E-Mail | |
// VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS | |
// usersRessource.get(userId).executeActionsEmail(Arrays.asList("UPDATE_PASSWORD")); | |
// Delete User | |
// userResource.remove(); | |
} | |
} |
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>com.github.thomasdarimont.keycloak</groupId> | |
<artifactId>keycloak-admin-client-example</artifactId> | |
<version>1.0.0.0-SNAPSHOT</version> | |
<properties> | |
<keycloak.version>8.0.2</keycloak.version> | |
<resteasy.version>3.9.1.Final</resteasy.version> | |
</properties> | |
<dependencies> | |
<dependency> | |
<artifactId>keycloak-admin-client</artifactId> | |
<groupId>org.keycloak</groupId> | |
<version>${keycloak.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.jboss.resteasy</groupId> | |
<artifactId>resteasy-client</artifactId> | |
<version>${resteasy.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.jboss.resteasy</groupId> | |
<artifactId>resteasy-jackson2-provider</artifactId> | |
<version>${resteasy.version}</version> | |
</dependency> | |
</dependencies> | |
</project> |
@thomasdarimont Isn't it possible to do it in one shot? Assign password and roles when creating the user? I tried but it seems not to work...
@AndreaNicola Credentials seem to work for me!
Hello, how do I use keycloak for its new versions?
If you still getting "HTTP 400 Bad request" error after following the tips and hints in this ticket or it suddenly stopped working, make sure the user account you are using does not have unresolved required actions such as verify email, fill in first name and last name etc. because you can't invoke direct grant if there are unresolved required actions!
I am using the latest version (24.0.3) at the time of writing this comment.
@maj2c Yes! That was it! Since the Firstname
and Lastname
fields are not marked as required in the Keycloak UI, I didn't bother filling them in. And, testing shows if either of these are missing it throws a 400! I think that is probably a bug? No?
this code will potentially lead to memory leaks since the Response is not closed after usage. If you try to make the call to this code multiple times to insert many users, your service/server will soon not be able to respond. You will need to make the try/finally and close on the response. This is quite tricky since everyone always assumes that a Response is just a Response, but it is indeed a Stream. You can check the documentation here https://docs.jboss.org/resteasy/docs/3.1.3.Final/userguide/html/RESTEasy_Client_Framework.html
I am using following to reset password but the password that I am passing does not meet password policy. Is there any way to get the correct error_description? I am getting "400 Bad request" error only.
userResource.resetPassword(passwordCred);
Hello! First of all thanks for the provided code, I have a question, is there any official documentation of how to use the
org.keycloak:keycloak-admin-client
??For sure your example is great but if I hadn't found this, it would be a nightmare to learn how to use it on the fly.