-
-
Save rosariop/0a689fe221760a3ce9cda77af0255f00 to your computer and use it in GitHub Desktop.
Adding User to keycloak and assigining a role
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//took me 4 weeks to figure that out due to some pretty bad documentation on the interwebs | |
//hope this helps you folks | |
@Component | |
public class KeycloakAdminService { | |
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); | |
@Value("${keycloak.auth-server-url}") | |
private String serverUrl; | |
@Value("${keycloak.realm}") | |
private String realm; | |
@Value("${keycloak.resource}") | |
private String clientId; | |
@Value("${admin-user}") | |
private String adminUsername; | |
@Value("${admin-password}") | |
private String adminPassword; | |
@Value("${keycloak.credentials.secret}") | |
private String secret; | |
private final Map<String, List<String>> roleMapping = new HashMap<>(); | |
public UserRepresentation createKeycloakUser(AppUser appUser) { | |
if (appUser instanceof Student) { | |
this.roleMapping.put(this.clientId, appUser.getKeycloakRoleAsList()); | |
} else if (appUser instanceof Teacher) { | |
this.roleMapping.put(this.clientId, appUser.getKeycloakRoleAsList()); | |
} else { | |
this.roleMapping.put(this.clientId, Collections.singletonList("")); | |
} | |
Keycloak adminKeycloak = getAdminKeycloak(); | |
CredentialRepresentation cr = new CredentialRepresentation(); | |
cr.setType(OAuth2Constants.PASSWORD); | |
cr.setValue(appUser.getPassword()); | |
UserRepresentation userRepresentation = new UserRepresentation(); | |
userRepresentation.setUsername(appUser.getUsername()); | |
userRepresentation.setClientRoles(roleMapping); | |
userRepresentation.setCredentials(Collections.singletonList(cr)); | |
userRepresentation.setEnabled(true); | |
adminKeycloak.realm(realm).users().create(userRepresentation); | |
List<UserRepresentation> userList = adminKeycloak.realm(realm).users().search(appUser.getUsername()).stream() | |
.filter(userRep -> userRep.getUsername().equals(appUser.getUsername())).collect(Collectors.toList()); | |
userRepresentation = userList.get(0); | |
logger.info("User with id: " + userRepresentation.getId() + " created"); | |
this.assignRoleToUser(userRepresentation.getId(), appUser.getKeycloakRoleAsList().get(0)); | |
return userRepresentation; | |
} | |
private void assignRoleToUser(String userId, String role) { | |
Keycloak keycloak = getAdminKeycloak(); | |
UsersResource usersResource = keycloak.realm(realm).users(); | |
UserResource userResource = usersResource.get(userId); | |
//getting client | |
ClientRepresentation clientRepresentation = keycloak.realm(realm).clients().findAll().stream().filter(client -> client.getClientId().equals(clientId)).collect(Collectors.toList()).get(0); | |
ClientResource clientResource = keycloak.realm(realm).clients().get(clientRepresentation.getId()); | |
//getting role | |
RoleRepresentation roleRepresentation = clientResource.roles().list().stream().filter(element -> element.getName().equals(role)).collect(Collectors.toList()).get(0); | |
//assigning to user | |
userResource.roles().clientLevel(clientRepresentation.getId()).add(Collections.singletonList(roleRepresentation)); | |
} | |
private Keycloak getAdminKeycloak() { | |
return KeycloakBuilder.builder().serverUrl(serverUrl) | |
.realm(realm) | |
.clientId(clientId) | |
.username(adminUsername) | |
.password(adminPassword) | |
.grantType("password") | |
.clientSecret(secret) | |
.resteasyClient( | |
new ResteasyClientBuilder() | |
.connectionPoolSize(10).build() | |
).build(); | |
} | |
public void deleteKeycloakUser(Student student) { | |
Keycloak keycloak = getAdminKeycloak(); | |
List<UserRepresentation> userList = keycloak.realm(realm).users().search(student.getUsername()); | |
for (UserRepresentation user : userList) { | |
if (user.getUsername().equals(student.getUsername())) { | |
keycloak.realm(realm).users().delete(user.getId()); | |
} | |
} | |
} | |
} |
Thanks for sharing, I've been struggling with toRepresentation()
for hours.
Works like a charm! Thank you very much
Can you show your pom.xml?
Can you show your pom.xml?
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>de.magister</groupId>
<artifactId>waterloo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>waterloo</name>
<description>Magister Media waterloo Service</description>
<properties>
<java.version>11</java.version>
<keycloak.version>10.0.2</keycloak.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.4.4</version>
</dependency>
</dependencies>
<packaging>jar</packaging>
<build>
<finalName>waterloo</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for sharing, but it didn't worked out for me. What finally solved it for me was to create role based groups and assign the group to the user as
userRepresentation.setGroups(Arrays.asList(request.getRole()));
This way there is no need for a 2-phase (create user, flush, add role), the above like is called before creating the user. Also the id's are no longer required, all you have to provide is the name of the group.