[BAEL-6161] Add example code for article. (#13651)
Co-authored-by: Uhrin Attila <attila.uhrin@frontendart.com>
This commit is contained in:
parent
c40bdd9f36
commit
ecad53efac
@ -17,6 +17,10 @@
|
|||||||
<relativePath>../../parent-boot-2</relativePath>
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<keycloak.version>21.0.1</keycloak.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -39,6 +43,41 @@
|
|||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
com.baeldung.keycloak.customendpoint.KeycloakUserApiProviderFactory
|
@ -0,0 +1 @@
|
|||||||
|
server.port=8081
|
Loading…
x
Reference in New Issue
Block a user