2016-09-23 48 views
0

我們使用Loopback for Node.js RESTful API。我們想知道我們是否可以利用模型上的先天訪問控制列表屬性來限制對特定用戶的特定記錄/對象的訪問。我希望這是可能的,而且我們不需要實現我們自己的邏輯。假設我們有兩個表像這樣(從Postgres):使用Loopback中的訪問控制列表來限制對錶記錄的訪問

contracts 
| id | name | manager_id | 
|----|------|-------------| 
| 1 | a | 4   | 
| 2 | b | 5   | 
| 3 | c | 6   | 

contract_managers 
| id | name | 
|----|------| 
| 4 | e | 
| 5 | f | 
| 6 | g | 

我們要的是實現低級別的訪問控制,合同臺 - 限制只有某些記錄用戶訪問。鑑於文檔,目前還不清楚我們是否可以單獨使用ACL來限制對特定記錄的訪問。

如果有人登錄了我們的應用程序,並且他們是contract_manager,我們希望他們只能從合同表中讀取記錄,其中manager_id是登錄用戶標識。例如,如果我登錄且我的用戶id = 4,則我是contract_manager,我應該只能從manager_id = 4的合同表中讀取。

有沒有一種方法可以實現這一點帶有ACL的簡單邏輯?或者我們是否需要創建自定義邏輯?

回答

1

如果您定義了custom role resolver,則可以執行此操作,然後添加具有限制特定訪問權限的ACL條目。

Role.registerResolver('$manager', function (role, ctx, callback) { 
    if (ctx.modelName === 'Contract') { 
    app.models.Contract.count({ 
     id: ctx.modelId, 

     // I'm assuming the ContractManager model extends User model. 
     // If instead there's a relation between ContractManager and User, 
     // Use include and scopes to filter it. 
     managerId: ctx.accessToken.userId, 
    }, function(err, count) { 
     if (err) { 
     callback(err); 
     } else if (count) { 
     callback(); 
     } else { 
     callback(new Error('Not Manager')); 
     } 
    }); 
    } else if (ctx.modelName === 'ContractManager') { 

    // Again making the same assumption about ContractManager. Chnage 
    // accordingly. 
    if (ctx.accessToken.userId === ctx.modelId) { 
     callback(); 
    } else { 
     process.nextTick(() => callback(new Error('Not Manager'))); 
    } 
    } else { 
    process.nextTick(() => callback(new Error('Only for ContractManager or Contract'))); 
    } 
} 

然後,你必須添加這個ACL(隨意使其更具體):

{ 
    "accessType": "*", 
    "principalType": "ROLE", 
    "principalId": "$manager", 
    "permission": "ALLOW", 
    "property": "*", 
    "model": "*" 
} 

現在請注意,這個角色解析與原型方法(即findById,/api/Contract/{id}),而不是隻適用使用靜態方法(即查找,/api/Contract),因爲我們使用ctx.modelId,它只能用於原型方法調用。