Express-Authz is an authorization middleware for Express, it's based on Node-Casbin
: https://github.com/casbin/node-casbin.
npm install casbin@2 casbin-express-authz@1 --save
npm install casbin@3 casbin-express-authz@2 --save
or you can simply use,
npm install express casbin casbin-express-authz --save
By default casbin-authz supports HTTP Basic Authentication of the form Authentication: Basic {Base64Encoded(username:password)}
To use other HTTP Authentication like Bearer/Digest
you can use a custom middleware to define the res.locals.username
variable and casbin-authz will automatically pick up the value from the variable.
const { newEnforcer } = require('casbin');
const express = require('express');
const { authz } = require('casbin-express-authz');
const app = express();
const enforcer = await newEnforcer('examples/authz_model.conf', 'examples/authz_policy.csv');
// set userinfo
app.use((req, res, next) => {
res.locals.username = getUsernameFromToken(); // Your custom function for retrieving username
next();
});
// use authz middleware
app.use(authz({ newEnforcer: enforcer }));
// response
app.use((req, res, next) => {
res.status(200).json({ status: 'OK' });
});
app.listen(3000);
This package provides BasicAuthorizer
, it uses HTTP Basic Authentication as the authentication method. If you want to use another authentication method like OAuth, you needs to implement Authorizer as below:
import { Enforcer, newEnforcer } from 'casbin';
import { authz, Authorizer } from 'casbin-express-authz';
import * as express from 'express';
const app = express();
class MyAuthorizer implements Authorizer {
private e: Enforcer;
constructor(e: Enforcer) {
this.e = e;
}
checkPermission(): Promise<boolean> {
// do something
return true;
}
}
const e = await newEnforcer('examples/authz_model.conf', 'examples/authz_policy.csv');
app.use(
authz({
newEnforcer: e,
authorizer: new MyAuthorizer(e),
})
);
app.listen(3000);
When the authorizer needs the request and response object to check the permission, one can pass the constructor of the customized Authorizer
class instead of an instance.
import { Enforcer, newEnforcer } from 'casbin';
import { authz, AuthorizerConstructor } from 'casbin-express-authz';
import { Request, Response } from 'express';
const app = express();
class MyAuthorizer implements Authorizer {
private e: Enforcer;
private req: Request;
private res: Respons;
constructor(req:Request, res:Respons, e: Enforcer) {
this.e = e;
this.req = req
this.res = res
}
checkPermission(): Promise<boolean> {
// do something
return true;
}
}
const e = await newEnforcer('examples/authz_model.conf', 'examples/authz_policy.csv');
app.use(
authz({
newEnforcer: e,
authorizer: MyAuthorizer,
})
);
app.listen(3000);
The authorization determines a request based on {subject, object, action}
, which means what subject
can perform what action
on what object
. In this plugin, the meanings are:
subject
: the logged-on user nameobject
: the URL path for the web resource like "dataset1/item1"action
: HTTP method like GET, POST, PUT, DELETE, or the high-level actions you defined like "read-file", "write-blog"
For how to write authorization policy and other details, please refer to the Casbin's documentation.
This project is licensed under the Apache 2.0 license.