# Role based access

**URL:** https://discourse.nodered.org/t/role-based-access/28666
**Category:** General
**Created:** [20 June 2020 18:53 UTC](https://discourse.nodered.org/t/role-based-access/28666 "2020-06-20T18:53:21Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![sarosh](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sarosh](https://discourse.nodered.org/u/sarosh)
#### Post date: [20 June 2020 18:53 UTC](https://discourse.nodered.org/t/role-based-access/28666/1 "2020-06-20T18:53:21Z")

</div>

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

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [20 June 2020 20:35 UTC](https://discourse.nodered.org/t/role-based-access/28666/2 "2020-06-20T20:35:07Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![sarosh](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sarosh](https://discourse.nodered.org/u/sarosh)
#### Post date: [20 June 2020 21:04 UTC](https://discourse.nodered.org/t/role-based-access/28666/3 "2020-06-20T21:04:28Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [20 June 2020 21:18 UTC](https://discourse.nodered.org/t/role-based-access/28666/4 "2020-06-20T21:18:25Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![sarosh](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sarosh](https://discourse.nodered.org/u/sarosh)
#### Post date: [24 June 2020 16:13 UTC](https://discourse.nodered.org/t/role-based-access/28666/5 "2020-06-24T16:13:27Z")

</div>

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.

```auto
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??

```auto
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);

```

---

<div class="post-metadata">

### Author: ![sarosh](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sarosh](https://discourse.nodered.org/u/sarosh)
#### Post date: [27 June 2020 15:15 UTC](https://discourse.nodered.org/t/role-based-access/28666/6 "2020-06-27T15:15:14Z")

</div>

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.

```auto
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);
        });
    }
}

```

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [11 July 2020 15:15 UTC](https://discourse.nodered.org/t/role-based-access/28666/7 "2020-07-11T15:15:17Z")

</div>

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