Search code examples
jbosstransactionskeycloakjtakeycloak-services

Keycloak java api fetch service account user for given client


I'm using Keycloak version 3.4.3.Final community version (I know it's an older version and cannot update it because of business reasons) and it's corresponding java client, I have created a client with flag serviceAccountEnabled set to true and need to assign realm-management client's roles to it i.e. from section service-account-roles.

I'm able to create client successfully but not able to assign realm-management client's roles to it as it requires fetching of service-account-user which is returning null everytime, below is my code snippet

Code to create client

            KeycloakTransaction tx = session.getTransactionManager();
            tx.begin();
            ClientModel clientModel = myRealm.addClient("myClient-id");
            clientModel.setClientId("myClient-id");
            clientModel.setClientAuthenticatorType("client-secret");
            clientModel.setStandardFlowEnabled(false);
            clientModel.setWebOrigins(Collections.emptySet());
            clientModel.setRedirectUris(Collections.emptySet());
            clientModel.setDirectAccessGrantsEnabled(false);
            clientModel.setImplicitFlowEnabled(false);
            clientModel.setServiceAccountsEnabled(true);
            clientModel.setPublicClient(false);
            clientModel.setProtocol("openid-connect");
            clientModel.setFullScopeAllowed(false);
            //need to inject this from env
            clientModel.setSecret("12345");
            clientModel.updateClient();
            commitOrRollbackTransaction(tx);

Code to assign realm-management roles to client's service-account-user

KeycloakTransaction tx = session.getTransactionManager();
tx.begin();
RealmModel myRealm = keycloakSession.realms().getRealmByName("myRealm");
ClientModel clientModel = myRealm.getClientByClientId("myClient-id");
ClientModel realmManagementClient = myRealm.getClientByClientId("realm-management");
Set<RoleModel> roles = realmManagementClient.getRoles();
UserModel serviceAccountUser = keycloakSession.users().getServiceAccount(clientModel);
if(serviceAccountUser != null){
   roles.stream().forEach(r -> serviceAccountUser.grantRole(r));
 }
tx.commit();

The issue is, I do not get service-account-user for the client I created in previous step, however I've verified that user got created, also I can fetch service-account-user for existing clients, it seems more like a transaction issue but I'm performing client creation and roles assignment in two different sessions.

Can someone please point me where I'm mistaking or point me to direction how to fetch service-account-user.


Solution

  • Got it working using RealmManager and ClientManager keycloak API.