使用 keycloak 分配用户角色“查看用户”

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

当我创建一个用户,然后我想用这个用户启动我的应用程序时,该用户需要具有这个角色:

如何将此角色分配给我的 user_id?为什么这是必要的?

keycloak
1个回答
0
投票

如何将此角色分配给我的 user_id?

您可以通过REST API分配角色

棘手的部分是你需要知道

{realm-management_id}
{view-users_role_id}

assign-role.js
展示了如何获取这些ID

REST API 端点

POST /admin/realms/{my-realm}/users/{user_id}/role-mappings/clients/{realm-management_id}

身体

[
   {
      "id":{view-users_role_id},
      "name":"view-users",
      "description":"${role_view-users}"
    }
]

Token:主令牌或领域管理员的令牌

邮递员的示例

node.js 的示例

另存为

assign-role.js

// assign-role.js
const axios = require('axios');

const getMasterToken = async (user_name, password) => {
    try {
        const resp = await axios.post(
            'http://localhost:8080/realms/master/protocol/openid-connect/token',
            new URLSearchParams({
                'client_id': 'admin-cli',
                'username': user_name,
                'password': password,
                'grant_type': 'password'
            })
        );
        return resp.data.access_token;
    } catch (err) {
        console.error(err);
    }
};

const getUser = async (token, username) => {
    try {
        const config = {
            headers: { Authorization: `Bearer ${token}` }
        };
        const url = `http://localhost:8080/admin/realms/my-realm/users/?username=${encodeURIComponent(username)}`;
        const response = await axios.get(url, config);

        if (response.status === 200) {
            return response.data;
        } else {
            console.error(`Failed to fetch user: Server responded with status ${response.status}`);
            return null;
        }
    } catch (error) {
        if (error.response) {
            console.error('Server responded with status:', error.response.status);
            console.error('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, clientName) => {
    try {
        const config = {
            headers: { Authorization: `Bearer ${token}` }
        };
        const url = `http://localhost:8080/admin/realms/my-realm/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);
            console.error('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 assignRole = async (token, userId, clientId, payload) => {
    try {
        const config = {
            headers: {
                Authorization: `Bearer ${token}`,
                'Content-Type': 'application/json'
            }
        };
        const url = `http://localhost:8080/admin/realms/my-realm/users/${userId}/role-mappings/clients/${clientId}`;
        const response = await axios.post(url, payload, config);

        if (response.status === 204) { // Status 204 No Content means the request was successful but the server is not returning any content
            return true;
        } else {
            console.error(`Failed to assign roles: Server responded with status ${response.status}`);
            return false;
        }
    } catch (error) {
        if (error.response) {
            console.error('Server responded with status:', error.response.status);
            console.error('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 false;
    }
};

const getClientRole = async (token, clientId, roleName) => {
    try {
        const config = {
            headers: {
                Authorization: `Bearer ${token}`
            }
        };
        const url = `http://localhost:8080/admin/realms/my-realm/clients/${clientId}/roles`;
        const response = await axios.get(url, config);

        if (response.status === 200 && response.data) {
            // Filter roles to find one that matches the roleName
            const role = response.data.find(r => r.name === roleName);
            return role || null; // Return the role if found, or null if not found
        } 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);
            console.error('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 master_token = await getMasterToken('admin', 'admin');

    const userName = 'user1';
    const userData = await getUser(master_token, 'user1');
    const userId = (userData) ? userData[0].id : null;

    if (userData) {
        console.log(`${userName} User ID:`, userId);
    }

    const clientName = 'realm-management';
    const clientData = await getClient(master_token, clientName);
    const clientId = (clientData) ? clientData[0].id : null;

    if (clientData) {
        console.log(`${clientName} Client ID:`, clientId);
    } else {
        console.error('Failed to fetch client data or client does not exist');
    }

    const roleName = "view-users";
    const role = await getClientRole(master_token, clientId, roleName);
    if (role) {
        const rolePayload = [{
            "id": `${role.id}`,
            "name": `${role.name}`,
            "description": `${role.description}`
        }];
        const result = await assignRole(master_token, userId, clientId, rolePayload);

        if (result) {
            console.log('Role assignment successful');
        } else {
            console.error('Failed to assign roles');
        }
    } else {
        console.error('Failed to get role');
    }
})();

安装依赖项

npm install axios

结果

为什么这是必要的?

该用户可以通过REST API获取用户列表

如果没有

view-users
角色,无法获取用户列表。

我会演示

user1
可以获取用户列表

user2
无法获取用户列表,他会得到403错误

另存为

get-users.js

// get-users.js
const axios = require('axios');

const getUserToken = async (user_name, password) => {
    try {
        const resp = await axios.post(
            'http://localhost:8080/realms/my-realm/protocol/openid-connect/token',
            new URLSearchParams({
                'client_id': 'admin-cli',
                'username': user_name,
                'password': password,
                'grant_type': 'password'
            })
        );
        return resp.data.access_token;
    } catch (err) {
        console.error(err);
    }
};

const getUsers = async (token) => {
    try {
        const config = {
            headers: { Authorization: `Bearer ${token}` }
        };
        const response = await axios.get('http://localhost:8080/admin/realms/my-realm/users', config);
        
        if (response.status === 200) {
            console.log('Successfully fetched users.');
            return response.data; // Return user data if response is successful
        } else {
            console.error(`Failed to fetch users: Server responded with status ${response.status}`);
            return null; // Return null or an appropriate value indicating the error
        }
    } catch (error) {
        if (error.response) {
            console.error('Server responded with status:', error.response.status);
            console.error('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; // Return null or an appropriate value indicating the error
    }
};

(async () => {
    const username = process.argv[2];
    const password = process.argv[3];
    
    const user_token = await getUserToken(username, password);
    const users = await getUsers(user_token);
    console.log('Users: ', users);
})();

User1
结果

User2
结果

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