I am using keycloak admin for user login and user creation. I was able to login a user thru my spring boot application and return a AccessTokenResponse
. For user creation I am getting a 403 response. I followed this tutorial and the UI is different now for Keycloak:21.1.0.
What I need to do is to add the manage-users to my client the old UI looks like this:
CODE:
Here's my KeycloackConfig
:
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@KeycloakConfiguration
public class KeycloakConfig {
@Value("${keycloak.auth-server-url}")
public String serverURL;
@Value("${keycloak.realm}")
public String realm;
@Value("${keycloak.resource}")
public String clientID;
@Value("${keycloak.credentials.secret}")
public String clientSecret;
@Bean
public Keycloak keycloak() {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverURL)
.clientId(clientID)
.clientSecret(clientSecret)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.build();
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Here's my KeycloakService
:
import lombok.RequiredArgsConstructor;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.core.Response;
import java.util.Collections;
@Service
@RequiredArgsConstructor
public class KeycloakService {
@Value("${keycloak.auth-server-url}")
private String serverURL;
@Value("${keycloak.realm}")
private String realm;
@Value("${keycloak.resource}")
private String clientID;
@Value("${keycloak.credentials.secret}")
private String clientSecret;
private final Keycloak keycloakAdminClient;
public void registerExisting(SignUpRequest request) {
this.createKeycloakUser(request);
}
public AccessTokenResponse login(LoginRequest request) {
try (Keycloak keycloak = this.keycloakCredentialBuilder(request)) {
return keycloak.tokenManager().getAccessToken();
} catch (NotAuthorizedException e) {
throw new KeycloakUnauthorizedException(e.getMessage());
} catch (BadRequestException e) {
throw new KeycloakBadRequestException(e.getMessage());
}
}
public void createKeycloakUser(SignUpRequest request) {
UsersResource usersResource = this.keycloakAdminClient.realm(this.realm).users();
CredentialRepresentation credentialRepresentation = createPasswordCredentials(request.getPassword());
UserRepresentation user = new UserRepresentation();
user.setUsername(request.getUsername());
user.setEmail(request.getEmail());
user.setFirstName(request.getFirstName());
user.setLastName(request.getLastName());
user.singleAttribute("phoneNumber",request.getPhoneNumber());
user.setCredentials(Collections.singletonList(credentialRepresentation));
try (Response response = usersResource.create(user)) {
if(response.getStatus() == 201) {
System.out.println("Created");
} else {
System.out.println(response.getStatus());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private Keycloak keycloakAdminBuilder() {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverURL)
.clientId(clientID)
.clientSecret(clientSecret)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.build();
}
private Keycloak keycloakCredentialBuilder(LoginRequest request) {
return KeycloakBuilder.builder()
.realm(this.realm)
.serverUrl(this.serverURL)
.clientId(this.clientID)
.clientSecret(this.clientSecret)
.username(request.getUsername())
.password(request.getPassword())
.build();
}
private CredentialRepresentation createPasswordCredentials(String password) {
CredentialRepresentation passwordCredentials = new CredentialRepresentation();
passwordCredentials.setTemporary(false);
passwordCredentials.setType(CredentialRepresentation.PASSWORD);
passwordCredentials.setValue(password);
return passwordCredentials;
}
}
QUESTIONS
The code was right. The problem was in configuration.
Here is the steps of how I resolved this:
manage-users
under realm-management
.This should respond 201 when you create a user. Took me days to figure this out. Hope that this post would help someone.