I need to get the clients of the composites of a role in the keycloak API
When I try to get the composite of a role the API returns JSON like this:
{
"id": "3bb6c58e-17c6-497f-8b7a-1febbc4d2777",
"name": "role1",
"description": "test",
"composite": false,
"clientRole": true,
"containerId": "b2ef8aaf-3dc7-44db-8cda-447ee1fccdee"
}
but I don't know which client this role pertences, is there some way to get the client of composites?
This API can get the client's role
GET http://localhost:8080/admin/realms/${realmName}/clients/${clientId}/roles
If you want to filter only composited roles, filter composite is true.
{
id: '<role uuid>',
name: '<role name>',
description: '<role description>',
composite: true,
clientRole: true,
containerId: '<client uuid>'
}
In here
demo.js
const axios = require('axios');
const getMasterToken = async (userName, password) => {
try {
const resp = await axios.post(
'http://localhost:8080/realms/master/protocol/openid-connect/token',
new URLSearchParams({
'client_id': 'admin-cli',
'username': userName,
'password': password,
'grant_type': 'password'
})
);
return resp.data.access_token;
} catch (err) {
console.error(err);
}
};
const getClients = async (token, realmName) => {
try {
const config = {
headers: { Authorization: `Bearer ${token}` }
};
const url = `http://localhost:8080/admin/realms/${realmName}/clients/`;
const response = await axios.get(url, config);
if (response.status === 200) {
return response.data;
} else {
console.error(`Failed to fetch client: Server responded with status ${response.status}`);
return null;
}
} catch (error) {
if (error.response) {
console.error('Server responded with status:', error.response.status, 'Response data:', error.response.data);
} else if (error.request) {
console.error('No response received:', error.request);
} else {
console.error('Error setting up request:', error.message);
}
return null;
}
};
const getClient = async (token, realmName, clientName) => {
try {
const config = {
headers: { Authorization: `Bearer ${token}` }
};
const url = `http://localhost:8080/admin/realms/${realmName}/clients/?clientId=${clientName}`;
const response = await axios.get(url, config);
if (response.status === 200) {
return response.data;
} else {
console.error(`Failed to fetch client: Server responded with status ${response.status}`);
return null;
}
} catch (error) {
if (error.response) {
console.error('Server responded with status:', error.response.status, 'Response data:', error.response.data);
} else if (error.request) {
console.error('No response received:', error.request);
} else {
console.error('Error setting up request:', error.message);
}
return null;
}
};
const getClientRoles = async (token, realmName, clientId, isComposite) => {
try {
const config = {
headers: {
Authorization: `Bearer ${token}`
}
};
const url = `http://localhost:8080/admin/realms/${realmName}/clients/${clientId}/roles`;
const response = await axios.get(url, config);
if (response.status === 200 && Array.isArray(response.data)) {
const roles = response.data.filter(r => typeof r.composite === 'boolean' && r.composite === isComposite);
return roles.length > 0 ? roles : null; // Return the filtered roles if any, otherwise null
} else {
console.error(`Failed to fetch roles: Server responded with status ${response.status}`);
return null;
}
} catch (error) {
if (error.response) {
console.error('Server responded with status:', error.response.status, 'Response data:', error.response.data);
} else if (error.request) {
console.error('No response received:', error.request);
} else {
console.error('Error setting up request:', error.message);
}
return null;
}
};
(async () => {
const masterToken = await getMasterToken('admin', 'admin');
const realmName = 'my-realm';
const clients = await getClients(masterToken, realmName);
for (const client of clients) {
const clientName = client.clientId;
const clientData = await getClient(masterToken, realmName, clientName);
const clientId = (clientData) ? clientData[0].id : null;
const roles = await getClientRoles(masterToken, realmName, clientId, true);
if (roles) {
console.log(`Client Name: ${clientName}, Client ID: ${clientId}`);
console.log(roles , '\n');
}
}
})();
npm install axios
node demo.js
Client Name: account, Client ID: c9f454f2-a111-4d47-850f-69a10f8f1691
[
{
id: '7e219a18-5a7d-4e9a-803e-4ccefa9802a8',
name: 'manage-consent',
description: '${role_manage-consent}',
composite: true,
clientRole: true,
containerId: 'c9f454f2-a111-4d47-850f-69a10f8f1691'
},
{
id: '72c57d15-02cb-4fbe-99e1-f815ad12b9de',
name: 'manage-account',
description: '${role_manage-account}',
composite: true,
clientRole: true,
containerId: 'c9f454f2-a111-4d47-850f-69a10f8f1691'
}
]
Client Name: realm-management, Client ID: f9cdff68-ce98-4112-b6c1-acacbd73dcfc
[
{
id: 'a69862d5-1ecc-4dc7-b223-78a4429c7778',
name: 'realm-admin',
description: '${role_realm-admin}',
composite: true,
clientRole: true,
containerId: 'f9cdff68-ce98-4112-b6c1-acacbd73dcfc'
},
{
id: '23aedd8c-4a1e-4506-a8a9-681cde8b9c8c',
name: 'view-clients',
description: '${role_view-clients}',
composite: true,
clientRole: true,
containerId: 'f9cdff68-ce98-4112-b6c1-acacbd73dcfc'
},
{
id: '8eae6bb1-4424-4cff-a09e-bab7304d8be4',
name: 'view-users',
description: '${role_view-users}',
composite: true,
clientRole: true,
containerId: 'f9cdff68-ce98-4112-b6c1-acacbd73dcfc'
}
]