2
votes

I created a Model named "ShippingAddresses" which has following ACL rules.

[
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW"
    },
    {
      "accessType": "EXECUTE",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "create"
    },
    {
      "accessType": "WRITE",
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW"
    }
  ]

When I create a record by making a POST call on endpoint /api/shipping_addresses it works perfectly fine but when I make a GET request on same endpoint /api/shipping_addresses it's not working.

Also, just for side note, I have ShippingAddresses model's relation defined with Account (inherits User). Relation is: User -> hasMany ShippingAddress , ShippingAddress -> belongsTo Account.

I read ACL documentation on Loopback Official docs but I'm lost. Everything seems to set correctly but still getting 401: Authorization Required.

3

3 Answers

2
votes

The problem lies in READ permission as you set it to $owner only. What it means is: only owner of a model instance can view that instance. Hence it will work only if you pass id for the instance related to the owner(User) i.e same as findById().

Also keep in mind, when working with ownership to model instance you must relate them with 'belongsTo'. What it will to do is add userId to the model instance, so that loopback knows to whom that model instance belongs to. Further it also creates new rest endpoints. For eg:

User.modelname.create()  //this way modelname instance is created for User.
                         //User is the owner of current modelname instance.

Otherwise if you want to allow everyone to access GET rest endpoints, use following ACL.

[
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW"
    },
    {
      "accessType": "EXECUTE",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "create"
    },
    {
      "accessType": "WRITE",
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW"
    }
  ]
0
votes

ACL is a one of the features of loopback framework. when compared to the other framework its useful for nodejs development. see your problem will properly created for the model will be change the role. first you refer to the authentication,and authrotation of loopback

will adding the coding for models/script.js https://github.com/strongloop/loopback-example-access-control/blob/master/common/models/project.js

0
votes

Loopback ACL ruins my half of day.

My issue is a different issue (about wrong role mapping data) but I think the process to get it works is the same.

My solution:

  1. Read carefully Loopback ACL precedence --> Can not figure out anything wrong
  2. Turn on DEBUG=loopback:security:* --> (In console) Lb tell me that it can not get role mapping
  3. Check mongo table. My role mapping is string instead of mongo's ObjectID
  4. Solve

@achintverma problem:

{
  "accessType": "*",
  "principalType": "ROLE",
  "principalId": "$everyone",
  "permission": "DENY"
},
{
  "accessType": "READ",
  "principalType": "ROLE",
  "principalId": "$owner",
  "permission": "ALLOW"
},

Above conf indicate that the $owner ALLOW READ take precedence over the $everyone DENY *.

If DEBUG was set, I can see sth like:

loopback:security:acl with score: 7495 +0ms

So 7495 is the score for each configuration, the largest score will be chosen.

but when I make a GET request on same endpoint /api/shipping_addresses it's not working.

Definitely because current user some how is not the $owner.