Loopback ACL: Static role not working

1,368 views
Skip to first unread message

Bobby Pilot

unread,
May 28, 2014, 5:55:21 PM5/28/14
to loopb...@googlegroups.com

I'm back at trying to figure out the the static role-based access in Loopback and once again I am stuck. I'm in need of basic role-based authorization.

  1. So I have created a role called "orgAdmin" via the Rest API. I did this by first opening the models.json and editing the "role" model to make public:true. I restarted the server, opened up the rest end point, and sent it this: {"name": "orgAdmin", "description": "Organization Administrator"} This worked fine, and the role was created.
  2. Next I created a user via the user rest end point like this: {"email":"em...@email.com", "password":"111111"} I verified the account was created by logging in. Again, worked great.
  3. Next, I create the RoleMapping (add a principal to the role). I grabbed the id of the the new role (/roles/{id}/principals) and the id of the new user and added the mapping like so: { "principalType": "USER", "principalId": "535dd89cf95491442a2e5e97" } This seems to have worked fine as well. I also used the roleMapping rest API specifically where I pass the roleId, principalType, and principalId like above they they seem to both update the role principals.
  4. Finally, I enable the acl in the models.json by adding the acl's section to my organization model like so: "org": { "options": { "acls": [ { "accessType": "*", "permission": "DENY", "principalType": "ROLE", "principalId": "$everyone" }, { "accessType": "*", "permission": "ALLOW", "principalType": "ROLE", "principalId": "orgAdmin" } ] }, "properties": { "orgName": { "type": "string" } }, "public": true, "dataSource": "db", "plural": "orgs" }

My issue is that once I enable Auth (app.enableAuth()), my user (who is supposed to be an orgAdmin) does not have access to perform any methods on the org model. If I change the principalId from "orgAdmin" to "$authenticated" then I do have access to GET and POST.

So what have I done wrong here? I'm following this doc:http://docs.strongloop.com/display/DOC/Defining+roles.

loopback 1.7.x

Any assistance is appreciated. Thanks

Raymond Feng

unread,
May 28, 2014, 6:09:49 PM5/28/14
to Bobby Pilot, loopb...@googlegroups.com
Hi, Bobby.

How did you map your user into the 'orgAdmin' role? Did you create a record to the RoleMapping model? 

When a request comes in, LoopBack will check the existence of access token and find the corresponding user object. It then checks if the user is member of a role that ACL entries use.

Thanks,

---
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc.

StrongLoop makes it easy to develop APIs in Node, plus get DevOps capabilities like monitoring, debugging and clustering.

--
You received this message because you are subscribed to the Google Groups "LoopbackJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to loopbackjs+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Bobby Pilot

unread,
May 28, 2014, 6:25:03 PM5/28/14
to loopb...@googlegroups.com, Bobby Pilot
Yes, in step 3 below I create the RoleMapping model via the roleMapping rest end point. I use the actual ID of the "orgAdmin" role as roleId. I use "USER" as the principalType and i use the users id as the principalId when defining the role mapping. 

{
  "roleId": "241g8sfd5gs098f0gksfgj43"
  "principalType": "USER",
  "principalId": "535dd89cf95491442a2e5e97"
}

Raymond Feng

unread,
May 28, 2014, 7:20:03 PM5/28/14
to Bobby Pilot, loopb...@googlegroups.com
How did you call the APIs on ‘org’ model? From the API explorer?

1. To invoke an API with the user credential, you’ll need to call User.login() first to get an access token. This can be done in the API explorer.

2. To call the API, append the access_token as a query parameter, for example:


Please note the API explorer doesn’t allow you to set up the access token. It’s a limitation. 

I was able to successfully to invoke POST to create a new org and GET it following the same steps you described.

Thanks,

---
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc.

StrongLoop makes it easy to develop APIs in Node, plus get DevOps capabilities like monitoring, debugging and clustering.

Bobby Pilot

unread,
May 28, 2014, 7:41:44 PM5/28/14
to loopb...@googlegroups.com, Bobby Pilot
That is exactly what I did yes. The access token is returned from the user/login api so I used that. Changing the principalId in the models.json to $authenticated allows me to read the orgs only if i pass the access_token. But I cannot get it to work with the orgAdmin role (of course after restarting and getting another token). Well bummer. I've got to be doing something stupid somewhere. :) I'll double check my code. Using loopback 1.7 shouldnt be a problem right?

Thanks a bunch for your prompt replies.

Bobby Hubbard

unread,
May 28, 2014, 9:55:13 PM5/28/14
to Ritchie Martori, loopb...@googlegroups.com

I'll give it a go. Thanks again

On May 28, 2014 7:28 PM, "Ritchie Martori" <rit...@strongloop.com> wrote:
Here is a hint for debugging the security bits in loopback:

`DEBUG=loopback:security:* node app.js`

This will print out a lot of useful info about the AccessContext / token / etc.

Bobby Pilot

unread,
May 28, 2014, 10:54:37 PM5/28/14
to loopb...@googlegroups.com, Ritchie Martori
I started from fresh and it works like a champ. Sorry for wasting your time. But I do feel better knowing I was headed down the right track. :) 

Matthew Williams

unread,
Jul 8, 2014, 10:40:42 PM7/8/14
to loopb...@googlegroups.com
So this question was asked a while back.  I am trying to implement an orgAdmin role which can change roles of users.   Setting up the role works well as described in the previous posts.  But what I would like to do is have a login for anyone (anonymously) to create a user account.   And then have a screen where an admin (role orgAdmin) could programattically change the users to a designated role.

So I created an orgAdmin designating a hasMany relationship to users.  I want all my users to belong to orgAdmin.  So that when a user account is created the orgAdmin can specify the role for the user.  So if I specify the user to belongTo orgAdmin...

Is that all that I have to do?

code example is below:

//models.json

//User Model

  "user": {
    "options": {
      "base": "User",
      "relations": {
        "accessTokens": {
          "model": "accessToken",
          "type": "hasMany",
          "foreignKey": "userId"
        },
        "locations": {
          "model": "location",
          "type": "hasMany",
          "foreignKey": "userId"
        },
"org":{
"model":"org",
"type":"belongsTo"
}
      }
    },

...

//Org Model
  "org": {
    "properties": {
        "id": {
          "type": "number",
          "id": true,
          "generated": true
        }
    },
    "public": true,
    "dataSource": "db",
"options":{
"relations": {
"user":{
"model":"user",
"type":"hasMany",
"foreignKey": "userId"
}
}
}

Raymond Feng

unread,
Jul 8, 2014, 10:59:04 PM7/8/14
to Matthew Williams, loopb...@googlegroups.com
Let me try to understand your use case:

1. There are two models: user and org. Each user belongs to an org and each org has many users.
2. You create a role named ‘orgAdmin’ in the role model
3. You add some users to the roleMapping model so that they are member of the ‘orgAdmin’ role.
4. Enforce ACLs for the roleMapping model so that only ‘orgAdmin’ can manipulate the role mappings (i.e., assigning/revoking users to/from roles).

I have a similar application. Here is what I did:

1. Declare the two models and relations in models.json as you do.
2. Use a config file to list emails/usernames that should be ‘orgAdmin’, find the user ids and use roleMapping.create() apis to add these users to the ‘orgAdmin’ role.
3. Enforce the roleMapping model (and other ones) with an ACL like:

"acls": [
        {
          "principalType": "ROLE",
          "principalId": “orgAdmin",
          "permission": "ALLOW"
        },
        {
          "principalType": "ROLE",
          "principalId": "$everyone",
          "property": "create",
          "permission": "DENY"
        }


Thanks,

---
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc.

StrongLoop makes it easy to develop APIs in Node, plus get DevOps capabilities like monitoring, debugging and clustering.

Reply all
Reply to author
Forward
0 new messages