Loopback: GET /Users or DELETE users always returns 401 Authorization required, even as admin

Created on 23 May 2017  路  11Comments  路  Source: strongloop/loopback

I've tried to create an admin that is allowed to list, update and delete users. I always get 401 authorization required on every API-request to the User-model.

Following official documentation and example-code, i used this code for /server/boot/create-models.js to create the admin:

  var User = app.models.User;
  var Role = app.models.Role;
  var RoleMapping = app.models.RoleMapping;
  var Team = app.models.Team;

  User.create([
    {username: 'admin', email: '[email protected]', password: 'admin'},
  ], function(err, users) {

    Role.create({
        name: 'admin'
      }, function(err, role) {
        if (err) throw err;

        console.log('Created role:', role);

        //make 'admin' an admin
        role.principals.create({
          principalType: RoleMapping.USER,
          principalId: users[0].id
        }, function(err, principal) {
          if (err) throw err;

          console.log('Created principal:', principal);
        });
      });
  });

Then i tried out the official Loopback-example-project for ACL and ran into the same issue.

Description/Steps to reproduce

1. Installation

git clone https://github.com/strongloop/loopback-example-access-control
cd loopback-example-access-control
npm install
node .

2. use the application

  1. open the API explorer in Webbrowser at http://0.0.0.0:3000/explorer
  2. Login as the Admin "bob":

_POST /users/login with body:_
{"email":"[email protected]", "password":"opensesame"}

I receive an access-token and pass it in the top bar textinput for access-token and click the button "set access-token".

  1. Try to list users with GET /users oder /users/count or all the other Endpoints for the User-Model including the DELETE method to a specific user.

Expected result

Every request returns:

{
  "error": {
    "statusCode": 401,
    "name": "Error",
    "message": "Authorization Required"
  }
}

I would expect to being able to list users, update users or delete users.

Additional information

The sample models and how the admin was created can be seen here:

It is the official example application, so i am not sure wether it is a (returned) bug of Loopback or the example application or a lack of documentation here.

stale

Most helpful comment

I'm facing a similar problem:
I used loopback-example-passport and connected the datasource as MongoDB.

While trying to access GET /users with ROLE $admin I'm getting 401

loopback:security:access-context --Context scopes of user.find()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +3ms
  loopback:security:role isInRole(): $everyone +298ms
  loopback:security:access-context ---AccessContext--- +1ms
  loopback:security:access-context principals: +1ms
  loopback:security:access-context principal: {"type":"USER","id":"596c49b9b9e7fb9bc24d0a0a"} +0ms
  loopback:security:access-context modelName user +1ms
  loopback:security:access-context modelId undefined +0ms
  loopback:security:access-context property find +0ms
  loopback:security:access-context method find +0ms
  loopback:security:access-context accessType READ +0ms
  loopback:security:access-context --Context scopes of user.find()-- +1ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 596c49b9b9e7fb9bc24d0a0a +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $everyone +0ms
  loopback:security:role isInRole(): $owner +1ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"596c49b9b9e7fb9bc24d0a0a"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId undefined +0ms
  loopback:security:access-context property find +0ms
  loopback:security:access-context method find +0ms
  loopback:security:access-context accessType READ +0ms
  loopback:security:access-context --Context scopes of user.find()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +1ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +1ms
  loopback:security:access-context   id "pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 596c49b9b9e7fb9bc24d0a0a +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $owner +0ms
  loopback:security:role isInRole(): $admin +1ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"596c49b9b9e7fb9bc24d0a0a"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId undefined +0ms
  loopback:security:access-context property find +0ms
  loopback:security:access-context method find +0ms
  loopback:security:access-context accessType READ +1ms
  loopback:security:access-context --Context scopes of user.find()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 596c49b9b9e7fb9bc24d0a0a +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Role found: {"id":"596c49bab9e7fb9bc24d0a0c","name":"$admin","created":"2017-07-17T05:23:05.805Z","modified":"2017-07-17T05:23:05.805Z"} +295ms
  loopback:security:role Role mapping found: null +1s
  loopback:security:role isInRole() returns: null +1ms
  loopback:security:acl The following ACLs were searched:  +1ms
  loopback:security:acl ---ACL--- +1ms
  loopback:security:acl model user +0ms
  loopback:security:acl property * +0ms
  loopback:security:acl principalType ROLE +0ms
  loopback:security:acl principalId $everyone +0ms
  loopback:security:acl accessType * +0ms
  loopback:security:acl permission DENY +0ms
  loopback:security:acl with score: 7495 +0ms
  loopback:security:acl ---Resolved--- +0ms
  loopback:security:access-context ---AccessRequest--- +1ms
  loopback:security:access-context  model user +0ms
  loopback:security:access-context  property find +0ms
  loopback:security:access-context  accessType READ +0ms
  loopback:security:access-context  permission DENY +0ms
  loopback:security:access-context  isWildcard() false +0ms
  loopback:security:access-context  isAllowed() false +0ms
Unhandled error for request GET /users?access_token=pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt: Error: Authorization Required

I've seemed to notice a difference:

  • If I use _Loopback InMemory_ connector then the _issue doesn't appear_.
  • But If I use _Loopback MongoDB_ connector then _I see this issue_.

The problem seems to occur in the https://github.com/strongloop/loopback/blob/master/common/models/role.js#L442

Somehow when using InMemory database, findOne returns the role "$admin" and therefore isInRole() returns true . But, incase of MongoDB findOne returns null even when the filter params are correct thus isInRole() returns false

I'm not sure, why this behavior is occuring. Please help.

All 11 comments

It's likely the ObjectID issue with mongodb connector if you are using mongoDB.
try add to the Models in model-config.js

    "options": {
         "strictObjectIDCoercion": true
    }

eg:

  "User": {
    "dataSource": "database",
    "public": true,
    "options": {
         "strictObjectIDCoercion": true
    }
  }

The user model has a pretty strict ACL from the loopback base denying access to all endpoints except for a few mostly limited to the model $owner (check node_modules\loopback\common\models\user.json ) and creating a role called admin does not make it an admin role. You need to define ACLs on the user model to allow endpoint access to the user model

eg.
"acls": [{
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW"
}]
in you local user.json model definition

I am getting a similar problem.

User.json ACLs

"acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW",
      "property": ["create", "login", "logout", "confirm"]
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW"
    },
    {
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "DENY",
      "property": "adminInvite",
      "accessType": "EXECUTE"
    },
    {
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW",
      "property": "resetPassword",
      "accessType": "EXECUTE"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "admin",
      "permission": "ALLOW"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW"
    },
    {
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW",
      "property": "link"
    }
  ],
loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +1ms
  loopback:security:role isInRole(): $everyone +53ms
  loopback:security:access-context ---AccessContext--- +1ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context property adminInvite +0ms
  loopback:security:access-context method adminInvite +0ms
  loopback:security:access-context accessType WRITE +0ms
  loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +1ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "1siev4E4qgNidmEYxTYJrQJyZrWPSrRpBG8vezB9Jy1DFNc2F5FObHm1X0Nfo5f4" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $everyone +0ms
  loopback:security:role isInRole(): $everyone +0ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"} +0ms
  loopback:security:access-context modelName user +1ms
  loopback:security:access-context modelId 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context property adminInvite +0ms
  loopback:security:access-context method adminInvite +0ms
  loopback:security:access-context accessType WRITE +0ms
  loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +1ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "1siev4E4qgNidmEYxTYJrQJyZrWPSrRpBG8vezB9Jy1DFNc2F5FObHm1X0Nfo5f4" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $everyone +0ms
  loopback:security:role isInRole(): $owner +0ms
  loopback:security:access-context ---AccessContext--- +1ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context property adminInvite +0ms
  loopback:security:access-context method adminInvite +0ms
  loopback:security:access-context accessType WRITE +0ms
  loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "1siev4E4qgNidmEYxTYJrQJyZrWPSrRpBG8vezB9Jy1DFNc2F5FObHm1X0Nfo5f4" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $owner +0ms
  loopback:security:role isOwner(): user 595bb27723a8de0eaff18892 userId: 595bb27723a8de0eaff18892 principalType: USER +1ms
  loopback:security:role isInRole(): $owner +0ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context property adminInvite +0ms
  loopback:security:access-context method adminInvite +0ms
  loopback:security:access-context accessType WRITE +0ms
  loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "1siev4E4qgNidmEYxTYJrQJyZrWPSrRpBG8vezB9Jy1DFNc2F5FObHm1X0Nfo5f4" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 595bb27723a8de0eaff18892 +1ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $owner +0ms
  loopback:security:role isOwner(): user 595bb27723a8de0eaff18892 userId: 595bb27723a8de0eaff18892 principalType: USER +0ms
  loopback:security:role isInRole(): admin +0ms
  loopback:security:access-context ---AccessContext--- +1ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context property adminInvite +0ms
  loopback:security:access-context method adminInvite +0ms
  loopback:security:access-context accessType WRITE +0ms
  loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "1siev4E4qgNidmEYxTYJrQJyZrWPSrRpBG8vezB9Jy1DFNc2F5FObHm1X0Nfo5f4" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role isInRole(): $everyone +1ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context property adminInvite +0ms
  loopback:security:access-context method adminInvite +0ms
  loopback:security:access-context accessType WRITE +0ms
  loopback:security:access-context --Context scopes of user.prototype.adminInvite()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "1siev4E4qgNidmEYxTYJrQJyZrWPSrRpBG8vezB9Jy1DFNc2F5FObHm1X0Nfo5f4" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 595bb27723a8de0eaff18892 +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $everyone +0ms
  loopback:security:role Role found: {"id":"595f1d784a467404ad00b144","name":"admin","created":"2017-07-07T05:34:48.853Z","modified":"2017-07-07T05:34:48.853Z"} +47ms
  loopback:security:role Role mapping found: null +49ms
  loopback:security:role isInRole() returns: null +1ms
  loopback:security:acl The following ACLs were searched:  +0ms
  loopback:security:acl ---ACL--- +1ms
  loopback:security:acl model user +0ms
  loopback:security:acl property adminInvite +0ms
  loopback:security:acl principalType ROLE +0ms
  loopback:security:acl principalId $owner +0ms
  loopback:security:acl accessType EXECUTE +0ms
  loopback:security:acl permission DENY +0ms
  loopback:security:acl with score: 8147 +0ms
  loopback:security:acl ---ACL--- +0ms
  loopback:security:acl model user +0ms
  loopback:security:acl property * +0ms
  loopback:security:acl principalType ROLE +1ms
  loopback:security:acl principalId $owner +0ms
  loopback:security:acl accessType * +0ms
  loopback:security:acl permission ALLOW +0ms
  loopback:security:acl with score: 7504 +0ms
  loopback:security:acl ---ACL--- +0ms
  loopback:security:acl model user +0ms
  loopback:security:acl property * +0ms
  loopback:security:acl principalType ROLE +0ms
  loopback:security:acl principalId $everyone +0ms
  loopback:security:acl accessType * +0ms
  loopback:security:acl permission DENY +0ms
  loopback:security:acl with score: 7495 +0ms
  loopback:security:acl ---ACL--- +0ms
  loopback:security:acl model user +0ms
  loopback:security:acl property * +0ms
  loopback:security:acl principalType ROLE +0ms
  loopback:security:acl principalId $everyone +1ms
  loopback:security:acl accessType * +0ms
  loopback:security:acl permission DENY +0ms
  loopback:security:acl with score: 7495 +0ms
  loopback:security:acl ---ACL--- +0ms
  loopback:security:acl model user +0ms
  loopback:security:acl property * +0ms
  loopback:security:acl principalType ROLE +0ms
  loopback:security:acl principalId $everyone +0ms
  loopback:security:acl accessType READ +0ms
  loopback:security:acl permission ALLOW +0ms
  loopback:security:acl with score: -1 +0ms
  loopback:security:acl ---Resolved--- +0ms
  loopback:security:access-context ---AccessRequest--- +0ms
  loopback:security:access-context  model user +0ms
  loopback:security:access-context  property adminInvite +0ms
  loopback:security:access-context  accessType WRITE +1ms
  loopback:security:access-context  permission DENY +0ms
  loopback:security:access-context  isWildcard() false +0ms
  loopback:security:access-context  isAllowed() false +0ms
Unhandled error for request POST /users/595bb27723a8de0eaff18892/adminInvite: Error: Authorization Required
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/loopback/lib/application.js:392:21
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/loopback/lib/model.js:353:7
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/loopback/common/models/acl.js:528:16
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:3861:9
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:421:16
    at iteratorCallback (/Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:998:13)
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:906:16
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:3858:13
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/loopback/common/models/acl.js:510:17
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/loopback/common/models/role.js:455:23
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:2779:17
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:421:16
    at iteratorCallback (/Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:998:13)
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:906:16
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/async/dist/async.js:2772:21
    at /Users/joaoribeiro/Documents/Projects/teezler/api/node_modules/loopback/common/models/role.js:446:15

Any idea?

Also some relevant functions

User.app.models.Role.create({
          name: 'admin',
        }, function(err, role) {
          if (err) {
            return cb(err);
          }
User.app.models.Role.findOne({where: {name: 'admin'}}, function (err, role) {
        if(err) return console.error(err);

        User.find({where: {email: {inq: ['[email protected]', '[email protected]', '[email protected]']}}}, function (err, users) {
          if(err) return console.error(err);

          for (var i = 0; i < users.length; i++) {
            role.principals.create({
              principalType: User.app.models.RoleMapping.USER,
              principalId: users[i].id,
            }, function() {});
          }
        });
      });

{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "DENY",
"property": "adminInvite",
"accessType": "EXECUTE"
}

Explicit DENY takes priority. I think you are making the call wrong:
loopback:security:access-context principal: {"type":"USER","id":"595bb27723a8de0eaff18892"}
POST /users/595bb27723a8de0eaff18892/adminInvite

I'm facing a similar problem:
I used loopback-example-passport and connected the datasource as MongoDB.

While trying to access GET /users with ROLE $admin I'm getting 401

loopback:security:access-context --Context scopes of user.find()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +3ms
  loopback:security:role isInRole(): $everyone +298ms
  loopback:security:access-context ---AccessContext--- +1ms
  loopback:security:access-context principals: +1ms
  loopback:security:access-context principal: {"type":"USER","id":"596c49b9b9e7fb9bc24d0a0a"} +0ms
  loopback:security:access-context modelName user +1ms
  loopback:security:access-context modelId undefined +0ms
  loopback:security:access-context property find +0ms
  loopback:security:access-context method find +0ms
  loopback:security:access-context accessType READ +0ms
  loopback:security:access-context --Context scopes of user.find()-- +1ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 596c49b9b9e7fb9bc24d0a0a +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $everyone +0ms
  loopback:security:role isInRole(): $owner +1ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"596c49b9b9e7fb9bc24d0a0a"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId undefined +0ms
  loopback:security:access-context property find +0ms
  loopback:security:access-context method find +0ms
  loopback:security:access-context accessType READ +0ms
  loopback:security:access-context --Context scopes of user.find()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +1ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +1ms
  loopback:security:access-context   id "pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 596c49b9b9e7fb9bc24d0a0a +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Custom resolver found for role $owner +0ms
  loopback:security:role isInRole(): $admin +1ms
  loopback:security:access-context ---AccessContext--- +0ms
  loopback:security:access-context principals: +0ms
  loopback:security:access-context principal: {"type":"USER","id":"596c49b9b9e7fb9bc24d0a0a"} +0ms
  loopback:security:access-context modelName user +0ms
  loopback:security:access-context modelId undefined +0ms
  loopback:security:access-context property find +0ms
  loopback:security:access-context method find +0ms
  loopback:security:access-context accessType READ +1ms
  loopback:security:access-context --Context scopes of user.find()-- +0ms
  loopback:security:access-context   method-level: ["DEFAULT"] +0ms
  loopback:security:access-context accessScopes ["DEFAULT"] +0ms
  loopback:security:access-context accessToken: +0ms
  loopback:security:access-context   id "pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt" +0ms
  loopback:security:access-context   ttl 1209600 +0ms
  loopback:security:access-context   scopes ["DEFAULT"] +0ms
  loopback:security:access-context getUserId() 596c49b9b9e7fb9bc24d0a0a +0ms
  loopback:security:access-context isAuthenticated() true +0ms
  loopback:security:role Role found: {"id":"596c49bab9e7fb9bc24d0a0c","name":"$admin","created":"2017-07-17T05:23:05.805Z","modified":"2017-07-17T05:23:05.805Z"} +295ms
  loopback:security:role Role mapping found: null +1s
  loopback:security:role isInRole() returns: null +1ms
  loopback:security:acl The following ACLs were searched:  +1ms
  loopback:security:acl ---ACL--- +1ms
  loopback:security:acl model user +0ms
  loopback:security:acl property * +0ms
  loopback:security:acl principalType ROLE +0ms
  loopback:security:acl principalId $everyone +0ms
  loopback:security:acl accessType * +0ms
  loopback:security:acl permission DENY +0ms
  loopback:security:acl with score: 7495 +0ms
  loopback:security:acl ---Resolved--- +0ms
  loopback:security:access-context ---AccessRequest--- +1ms
  loopback:security:access-context  model user +0ms
  loopback:security:access-context  property find +0ms
  loopback:security:access-context  accessType READ +0ms
  loopback:security:access-context  permission DENY +0ms
  loopback:security:access-context  isWildcard() false +0ms
  loopback:security:access-context  isAllowed() false +0ms
Unhandled error for request GET /users?access_token=pNIPzaooWDWDFBFESdc0yZ4hBIGw7dJRCE2utxWXHOrVeMzGCrFRgYPzpqEhI6Gt: Error: Authorization Required

I've seemed to notice a difference:

  • If I use _Loopback InMemory_ connector then the _issue doesn't appear_.
  • But If I use _Loopback MongoDB_ connector then _I see this issue_.

The problem seems to occur in the https://github.com/strongloop/loopback/blob/master/common/models/role.js#L442

Somehow when using InMemory database, findOne returns the role "$admin" and therefore isInRole() returns true . But, incase of MongoDB findOne returns null even when the filter params are correct thus isInRole() returns false

I'm not sure, why this behavior is occuring. Please help.

I'm also facing the same problem. Admin cannot delete/update/reset password of other users.
My user model is:

{
"name": "user",
"base": "User",
"inheritAcls": false,
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"uid": {
"type": "string"
},
"name": {
"type": "string",
"required": true
},
"picture": {
"type": "string",
"required": true
},
"email": {
"type": "string",
"required": true
},
"phone": {
"type": [
"string"
],
"required": true
},
"birthday":{
"type": "date"
},
"bio": {
"type": "string"
},
"address": {
"type": "string"
},
"location": {
"type": "geopoint"
},
"created_at": {
"type": "date",
"required": true
},
"updated_at": {
"type": "date",
"required": true
}
},
"validations": [],
"relations": {
"posts": {
"type": "hasMany",
"model": "post",
"foreignKey": ""
},
"comments": {
"type": "hasMany",
"model": "comment",
"foreignKey": ""
},
"settings": {
"type": "hasOne",
"model": "settings",
"foreignKey": ""
}
},
"acls": [
{
"accessType": "",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
},
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW",
"property": "create"
},
{
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "resetPassword"
},
{
"accessType": "
",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW"
},
{
"accessType": "",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW",
"property": "deleteById"
},
{
"accessType": "
",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW",
"property": "updateAttributes"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW",
"property": "resetPassword"
}
],
"methods": {}
}

Still I get this response:

{
"error": {
"statusCode": 401,
"name": "Error",
"message": "Authorization Required",
"code": "AUTHORIZATION_REQUIRED",
"stack": "Error: Authorization Required\n at /someDirectory/node_modules/loopback/lib/application.js:399:21\n at /someDirectory/node_modules/loopback/lib/model.js:349:7\n at /someDirectory/node_modules/loopback/common/models/acl.js:472:23\n at /someDirectory/node_modules/async/dist/async.js:3861:9\n at /someDirectory/node_modules/async/dist/async.js:421:16\n at iteratorCallback (/someDirectory/node_modules/async/dist/async.js:998:13)\n at /someDirectory/node_modules/async/dist/async.js:906:16\n at /someDirectory/node_modules/async/dist/async.js:3858:13\n at /someDirectory/node_modules/loopback/common/models/acl.js:454:17\n at /someDirectory/node_modules/loopback/common/models/role.js:343:23\n at /someDirectory/node_modules/loopback-datasource-juggler/lib/dao.js:2081:62\n at /someDirectory/node_modules/loopback-datasource-juggler/lib/dao.js:2009:11\n at /someDirectory/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:396:17\n at async.each (/someDirectory/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:153:20)\n at _asyncMap (/someDirectory/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:390:13)\n at Object.map (/someDirectory/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:361:23)"
}
}

How to delete other users via api? Is there any thing I need to set=true or should I write my own function for that?

I think this is not only with MongoDB.
I'm using with PostgreSQL connector and I get the same error.
It seems to be a problem when you try to link to a database.
I did exactly the same things as previous.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository.

I just cloned https://github.com/strongloop/loopback-sandbox.git and tried to run the project as-is, using in-memory connector and I'm facing the same issue.

Using the /explorer, I created a new user, logged in, set the token and then tried to get some resources of this user:

  • GET /users
  • HEAD /Users/{id}
  • GET /users/{id}/accessTokens

Added a boot script to create an admin, logged in, set the token and same problem happened.

Was this page helpful?
0 / 5 - 0 ratings