[BAEL-6161] Add example code for article. (#13651)

Co-authored-by: Uhrin Attila <attila.uhrin@frontendart.com>
This commit is contained in:
AttilaUhrin 2023-03-31 04:23:12 +02:00 committed by GitHub
parent c40bdd9f36
commit ecad53efac
7 changed files with 246 additions and 0 deletions

View File

@ -17,6 +17,10 @@
<relativePath>../../parent-boot-2</relativePath>
</parent>
<properties>
<keycloak.version>21.0.1</keycloak.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -39,6 +43,41 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-admin-client -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<scope>provided</scope>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<version>${keycloak.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
<scope>provided</scope>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<scope>provided</scope>
<version>${keycloak.version}</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,90 @@
package com.baeldung.keycloak.adminclient;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AdminClientService {
private static final Logger logger = LoggerFactory.getLogger(AdminClientService.class);
private static final String REALM_NAME = "master";
@Autowired
private Keycloak keycloak;
@PostConstruct
public void searchUsers() {
logger.info("Searching users in Keycloak {}", keycloak.serverInfo()
.getInfo()
.getSystemInfo()
.getVersion());
searchByUsername("user1", true);
searchByUsername("user", false);
searchByUsername("1", false);
searchByEmail("user2@test.com", true);
searchByAttributes("DOB:2000-01-05");
searchByGroup("c67643fb-514e-488a-a4b4-5c0bdf2e7477");
searchByRole("user");
}
private void searchByUsername(String username, boolean exact) {
logger.info("Searching by username: {} (exact {})", username, exact);
List<UserRepresentation> users = keycloak.realm(REALM_NAME)
.users()
.searchByUsername(username, exact);
logger.info("Users found by username {}", users.stream()
.map(user -> user.getUsername())
.collect(Collectors.toList()));
}
private void searchByEmail(String email, boolean exact) {
logger.info("Searching by email: {} (exact {})", email, exact);
List<UserRepresentation> users = keycloak.realm(REALM_NAME)
.users()
.searchByEmail(email, exact);
logger.info("Users found by email {}", users.stream()
.map(user -> user.getEmail())
.collect(Collectors.toList()));
}
private void searchByAttributes(String query) {
logger.info("Searching by attributes: {}", query);
List<UserRepresentation> users = keycloak.realm(REALM_NAME)
.users()
.searchByAttributes(query);
logger.info("Users found by attributes {}", users.stream()
.map(user -> user.getUsername() + " " + user.getAttributes())
.collect(Collectors.toList()));
}
private void searchByGroup(String groupId) {
logger.info("Searching by group: {}", groupId);
List<UserRepresentation> users = keycloak.realm(REALM_NAME)
.groups()
.group(groupId)
.members();
logger.info("Users found by group {}", users.stream()
.map(user -> user.getUsername())
.collect(Collectors.toList()));
}
private void searchByRole(String roleName) {
logger.info("Searching by role: {}", roleName);
List<UserRepresentation> users = keycloak.realm(REALM_NAME)
.roles()
.get(roleName)
.getUserMembers();
logger.info("Users found by role {}", users.stream()
.map(user -> user.getUsername())
.collect(Collectors.toList()));
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.keycloak.adminclient;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication(scanBasePackages = { "com.baeldung.keycloak.adminclient" })
@PropertySource("classpath:application-adminclient.properties")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
Keycloak keycloak() {
return KeycloakBuilder.builder()
.serverUrl("http://localhost:8080")
.realm("master")
.clientId("admin-cli")
.grantType(OAuth2Constants.PASSWORD)
.username("admin")
.password("password")
.build();
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.keycloak.customendpoint;
import java.util.Optional;
import java.util.stream.Stream;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.resource.RealmResourceProvider;
public class KeycloakUserApiProvider implements RealmResourceProvider {
private final KeycloakSession session;
public KeycloakUserApiProvider(KeycloakSession session) {
this.session = session;
}
public void close() {
}
public Object getResource() {
return this;
}
@GET
@Produces({ MediaType.APPLICATION_JSON })
public Stream<UserRepresentation> searchUsersByGroupAndRoleName(@QueryParam("groupName") @NotNull String groupName, @QueryParam("roleName") @NotBlank String roleName) {
RealmModel realm = session.getContext().getRealm();
Optional<GroupModel> groupByName = session.groups()
.getGroupsStream(realm)
.filter(group -> group.getName().equals(groupName))
.findAny();
GroupModel group = groupByName.orElseThrow(() -> new NotFoundException("Group not found with name " + groupName));
return session.users()
.getGroupMembersStream(realm, group)
.filter(user -> user.getRealmRoleMappingsStream().anyMatch(role -> role.getName().equals(roleName)))
.map(user -> ModelToRepresentation.toBriefRepresentation(user));
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.keycloak.customendpoint;
import org.keycloak.Config.Scope;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resource.RealmResourceProviderFactory;
public class KeycloakUserApiProviderFactory implements RealmResourceProviderFactory {
public static final String ID = "users-by-group-and-role-name";
@Override
public RealmResourceProvider create(KeycloakSession session) {
return new KeycloakUserApiProvider(session);
}
@Override
public void init(Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return ID;
}
}

View File

@ -0,0 +1 @@
com.baeldung.keycloak.customendpoint.KeycloakUserApiProviderFactory