imicros-acl
Version:
Moleculer service for access control
166 lines (147 loc) • 5.8 kB
Markdown
[](https://travis-ci.org/al66/imicros-acl)
[](https://coveralls.io/github/al66/imicros-acl?branch=master)
```
$ npm install imicros-acl --save
```
Requires
- a running [Neo4j](https://neo4j.com/) instance - refer to [example](#Docker).
- imicros-groups service for managing the groups
The service expects user id and email to be set in ctx.meta data as follows:
```
ctx.meta.user = {
id: 'unique ID of the user (number or string)',
email: 'user@test.org'
}
```
Otherwise the service throws <code>not authenticated</code> error.
```
const { Acl } = require("imicros-acl");
```
```
await broker.createService(Acl, Object.assign({
settings: {
uri: process.env.NEO4J_URI || "bolt://localhost:7687",
user: process.env.NEO4J_USER || "neo4j",
password: process.env.NEO4J_PASSSWORD || "neo4j"
}
}));
```
- requestAccess { forGroupId } => { token }
- verify { token } => { acl }
- addGrant { forGroupId, ruleset } => { result } only for group admins
- removeGrant { forGroupId } => { result } only for group admins
For ruleset language refer to imicros-rules-compiler.
The ruleset is called with the parameters
- user: ctx.meta.user
- ressource: parameter of call isAuthorized
- action: parameter of call isAuthorized
To get access for ressources of a group, an access token must be requested by calling <code>acl.requestAccess</code>.
If the authenticated user in <code>ctx.meta.user.id</code> is member of the requested group <code>forGroupId</code> a token with unrestricted access is issued.
If the authenticated user in <code>ctx.meta.user.id</code> is member of a group where grants are assigned to the requested group <code>forGroupId</code> a token with restricted access is issued.
If the authenticated user in <code>ctx.meta.user.id</code> is neither a member nor a grant to one of his groups is assigned, no access token will be issued.
The retrieved access token must be delivered in the service call context under <code>ctx.meta.acl.accessToken</code>.
This token is verified by the broker middleware.
The final authorization check is made in the mixin method <code>isAuthorized</code>.
In case of restricted access the grant rulesets are called. If no grant solves to <code>acl.result = 'allow'</code> the access is denied.
```
const { AclMixin } = require("imicros-acl");
```
```
const Service = {
name: "AnyService",
settings: {
acl: {
service: "acl" // name of the acl service
}
},
mixins: [AclMixin],
actions: {
...
```
```
// call method of acl mixin
await this.isAuthorized({
ctx: ctx, // context from action handler
ressource: res, // JSON representation of the ressource - attributes can be used in grant rules
action: 'read' // name of the called action or a specific command like read,write,update'
});
```
The original called action is also available in grant rules under <code>environment.action</code>.
```
const { AclMiddleware } = require("imicros-acl");
```
```
broker = new ServiceBroker({
logger: console,
logLevel: "info",
middlewares: [AclMiddleware]
});
```
The middleware wraps localAction and verifies a given accesstoken in <code>ctx.meta.acl.accessToken</code> by calling service <code>acl.verify</code>.
If successful verified further acl parameter are set which are used by <code>isAuthorized</code> method of the mixin or direct in the middleware.
The acl check by the middleware can be triggered by an acl parameter in the action defintion:
```
const Service = {
name: "service",
actions: {
get1: {
acl: "before", // acl check in the middleware is done before the action is called
async handler(ctx) {
...
return true;
}
},
get2: {
acl: "after", // acl check in the middleware is done after the action is called and can be now based on the result
// this is only useful in case of ruleset based grants
async handler(ctx) {
...
return { test: { a: "yes" } };
}
},
get3: {
acl: "always", // acl check in the middleware is done before and after the action is called
// this is only useful in case of ruleset based grants
async handler(ctx) {
...
return { test: { a: "yes" } };
}
},
get4: {
acl: "core", // access only for admin group created during initial start of the groups service
async handler(ctx) {
...
return { test: { core: "yes" } };
}
}
}
};
```
```
version: '3'
services:
neo4j:
image: neo4j
container_name: neo4j
ports:
- "7474:7474"
- "7687:7687"
volumes:
- ./data:/data
```