如何在Keycloak API中获取组合的客户端

问题描述 投票:0回答:1

我需要获取 keycloak API 中角色组合的客户端

当我尝试获取角色的组合时,API 返回如下 JSON:

{
        "id": "3bb6c58e-17c6-497f-8b7a-1febbc4d2777",
        "name": "role1",
        "description": "test",
        "composite": false,
        "clientRole": true,
        "containerId": "b2ef8aaf-3dc7-44db-8cda-447ee1fccdee"
}

但是我不知道这个角色属于哪个客户端,有什么办法可以获取composite的客户端吗?

json keycloak keycloak-rest-api keycloak-gatekeeper
1个回答
0
投票

此API可以获取客户端的角色

GET http://localhost:8080/admin/realms/${realmName}/clients/${clientId}/roles

如果只想过滤复合角色,则过滤复合为true。

{
    id: '<role uuid>',
    name: '<role name>',
    description: '<role description>',
    composite: true,
    clientRole: true,
    containerId: '<client uuid>'
}

通过 docker compose 启动 Keycloak

这里

演示

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');
        }
    }
})();

结果

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'
  }
]

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.