Role based access

Hi, I wanted to know is there Role based access control in node red? Can we give permissions based on user roles?

What sort of thing do you mean? What type of roles did you have in mind and what permissions would you want them to have?

In the adminAuth section, the permissions are given based on username. Like a username admin has [ "" ] some other user with username user1 has[ "read" ]. So instead of having usernames I want to be roles instead. I have set roles for users in my keycloak portal. I want one role to be admin who has [ "" ] permission and so on... So I create multiple users under same role and in settings.js I only have to define role and not specific username.

If you are using a custom adminAuth strategy for keycloak, then you could probably get the role back from keycloak profile and then turn it into the appropriate set of permissions to return for that user.

I can't give a more concrete example as it's not something I've done, but I think the pieces are all there.

Hi, Thanks to your reply, I created the below code to login using REST API. But when I login I cannot access pages. I have verified I get the access_token and get role from it. Can you help or point what I am missing or doing wrong.

var request = require('request');
var jwt = require('jsonwebtoken');
const { valid } = require('semver');

module.exports = {

    type: "credentials",
    users: function (username) {
        return new Promise(function (resolve) {
            // Do whatever work is needed to check username is a valid
            // user.
            var valid = true;
            if ('admin' != username || 'user' != username) {
                valid = false;
            }

            if (valid) {

                // Resolve with the user object. It must contain
                // properties 'username' and 'permissions'
                if ('admin' == username) {
                    var user = { username: "admin", permissions: "*" };
                } else if ('user' == username) {
                    var user = { username: "user", permissions: "read" };
                } else {
                    resolve(null);
                }
                resolve(user);
            } else {
                // Resolve with null to indicate this user does not exist
                resolve(null);
            }

        });

    },

    authenticate: function (username, password) {

        return new Promise(function (resolve) {

            // Do whatever work is needed to validate the username/password
            // combination.
            console.log("Sending aunthentication request to keyclock");

            var options = {
                'method': 'POST',
                'url': 'https://auth.example.com/auth/realms/MyRealm/protocol/openid-connect/token',
                'headers': {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },

                form: {
                    'grant_type': 'password',
                    'username': username,
                    'password': password,
                    'client_id': 'node-red',
                    'client_secret': 'my-secret',
                    'scope': ''
                }

            };

            request(options, function (error, response) {

                if (error) {
                    console.log("Error authenticating: " + error);
                    resolve(null);
                    return;
                }

                var bodyObj = JSON.parse(response.body);
                var jwtObj = jwt.decode(bodyObj.access_token);
                console.log("Got access_token");
                console.log("role: "+jwtObj.roles[0]);
                var user = null;

                if (jwtObj.roles[0]=='admin') {
                    console.log("permissions: *");
                    user = { username: jwtObj.roles[0], permissions: "*" };
                } else if (jwtObj.roles[0]=='user') {
                    console.log("permissions: read");
                    user = { username: jwtObj.roles[0], permissions: "read" };
                } 

                resolve(user);
            });

        });

    },

    default: function () {
        return new Promise(function (resolve) {
            // Resolve with the user object for the default user.
            // If no default user exists, resolve with null.
            resolve({ anonymous: true, permissions: "read" });
        });
    }
}

EDIT: It tuns out it is saving username. I checked by logging it in users function, but I a returning admin and it is saving the actual username. Is there a way to use local storage??

users: function (username) {
        return new Promise(function (resolve) {
            // Do whatever work is needed to check username is a valid
            // user.
            console.log("Verfying user: "+username);

Hi guys, so I have done role based authorization with a work around and it works pretty fine for now, it is not the best but it works.

var request = require('request');
var jwt = require('jsonwebtoken');
const { valid } = require('semver');

var loggedInUser = null;

module.exports = {
    type: "credentials",
    users: function (username) {
        return new Promise(function (resolve) {
            resolve(loggedInUser);
        });
    },

    authenticate: function (username, password) {
        return new Promise(function (resolve) {
            
            var options = {
                'method': 'POST',
                'url': 'https://auth.example.comauth/realms/MyRealme/protocol/openid-connect/token',
                'headers': {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                form: {
                    'grant_type': 'password',
                    'username': username,
                    'password': password,
                    'client_id': 'my-client',
                    'client_secret': 'my-sercre',
                    'scope': ''
                }
            };

            request(options, function (error, response) {
                if (error) {
                    resolve(null);
                    return;
                }

                var bodyObj = JSON.parse(response.body);
                var jwtObj = jwt.decode(bodyObj.access_token);
                var user = null;

                if (jwtObj.roles.filter(e => e == 'admin').length > 0) {
                    user = { username: jwtObj.roles[0], permissions: "*" };
                    loggedInUser = { username: username, permissions: "*" };
                } else if (jwtObj.roles.filter(e => e == 'user').length > 0) {
                    user = { username: jwtObj.roles[0], permissions: "read" };
                    loggedInUser = { username: username, permissions: "read" };
                }
                resolve(user);
            });
        });
    },

    default: function () {
        return new Promise(function (resolve) {
            // If no default user exists, resolve with null.
            //resolve({ anonymous: true, permissions: "read" });
            resolve(null);
        });
    }
}

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.