@labshare/services-auth
Advanced tools
Comparing version 2.0.2 to 2.1.0
@@ -0,1 +1,8 @@ | ||
# [2.1.0](https://github.com/LabShare/services-auth/compare/v2.0.2...v2.1.0) (2018-08-22) | ||
### Features | ||
* **api:** export generic RS256 middleware for Express.js AUTH-1315 ([20e4509](https://github.com/LabShare/services-auth/commit/20e4509)) | ||
## [2.0.2](https://github.com/LabShare/services-auth/compare/v2.0.1...v2.0.2) (2018-08-22) | ||
@@ -2,0 +9,0 @@ |
144
lib/index.js
'use strict'; | ||
const restrictRoute = require('./restrict-route'), | ||
restrictSocket = require('./restrict-socket'), | ||
authUser = require('./user'), | ||
deprecate = require('deprecate'), | ||
{each} = require('lodash'), | ||
jwt = require('express-jwt'), | ||
jwtAuthz = require('express-jwt-authz'), | ||
jws = require('jsonwebtoken'), | ||
socketRS256 = require('./socket/rs256'), | ||
jwksClient = require('jwks-rsa'), | ||
getBearerToken = require('./utils/get-bearer-token'), | ||
jwtAuthzSocket = require('./jwt-authz-socket'); | ||
const restrictRoute = require('./restrict-route'); | ||
const restrictSocket = require('./restrict-socket'); | ||
const authUser = require('./user'); | ||
const deprecate = require('deprecate'); | ||
const {each} = require('lodash'); | ||
const jwt = require('express-jwt'); | ||
const jwtAuthz = require('express-jwt-authz'); | ||
const jws = require('jsonwebtoken'); | ||
const socketRS256 = require('./socket/rs256'); | ||
const jwksClient = require('jwks-rsa'); | ||
const getBearerToken = require('./utils/get-bearer-token'); | ||
const jwtAuthzSocket = require('./jwt-authz-socket'); | ||
const defaultJwksClientOptions = { | ||
cache: true, | ||
rateLimit: true, // See: https://github.com/auth0/node-jwks-rsa#rate-limiting | ||
jwksRequestsPerMinute: 10 | ||
}; | ||
const DEPRECATION_NOTICE = `LabShare API "accessLevel" authorization is deprecated. Please check https://github.com/LabShare/services-auth#usage for more info.`; | ||
@@ -36,28 +41,2 @@ | ||
/** | ||
* @description Validate Authorization Bearer Token using RS256 if it exists as a request header. | ||
* @param secret | ||
* @param audience | ||
* @param issuer | ||
* @returns {function(*=, *=, *=)} | ||
* @private | ||
*/ | ||
function httpRS256({secret, audience, issuer}) { | ||
return function rs256(req, res, next) { | ||
jwt({ | ||
getToken: getBearerToken, | ||
secret, | ||
audience, // Optionally validate the audience and the issuer as well | ||
issuer | ||
})(req, res, (error) => { | ||
if (error) { | ||
res.status(401).send(error.message); | ||
return; | ||
} | ||
next(); | ||
}); | ||
} | ||
} | ||
/** | ||
* @description Verify JWT audience | ||
@@ -93,2 +72,44 @@ * @param audience | ||
/** | ||
* @description RS256 route authentication middleware for Express.js. It validates the Authorization Bearer token | ||
* request header. | ||
* @param {String} [authUrl] - The base URL for the LabShare Auth service. Optional if `secretProvider` is specified. | ||
* @param {String} [tenant] - A LabShare Auth Tenant. Optional if `secretProvider` is specified. | ||
* @param {String} [audience] - A unique identifier for the API service registered as a Resource Server in LabShare Auth | ||
* @param {String} [issuer] - Validate JWT issuer claim against the expected value | ||
* @param {Function|null} secretProvider - Custom function for obtaining the RS256 signing certificate. Function signature: (req, header, payload, cb). | ||
* @returns Express.js middleware function | ||
* @public | ||
*/ | ||
function expressRs256({ | ||
authUrl = null, | ||
tenant = null, | ||
secretProvider = null, | ||
audience = null, | ||
issuer = null | ||
}) { | ||
if (!authUrl && !secretProvider) { | ||
throw new Error('`authUrl` is required'); | ||
} | ||
if (!tenant && !secretProvider) { | ||
throw new Error('`tenant` is required'); | ||
} | ||
const jwksClientOptions = { | ||
...defaultJwksClientOptions, | ||
jwksUri: `${authUrl}/auth/${tenant}/.well-known/jwks.json` | ||
}; | ||
const secret = secretProvider || jwksClient.expressJwtSecret(jwksClientOptions); | ||
// Validate JWT in Authorization Bearer header using RS256 | ||
return jwt({ | ||
getToken: getBearerToken, | ||
secret, | ||
audience, // Optionally validate the audience and the issuer as well | ||
issuer | ||
}); | ||
} | ||
/** | ||
* @description Enables Resource Scope authorization on LabShare Service API routes and sockets using RS256 for JWT validation. | ||
@@ -104,3 +125,9 @@ * @param {String} [authUrl] - The base URL for the LabShare Auth service. Optional if `secretProvider` is specified. | ||
*/ | ||
module.exports = function authorize({authUrl, tenant, secretProvider = null, audience = null, issuer = null}) { | ||
function authorize({ | ||
authUrl = null, | ||
tenant = null, | ||
secretProvider = null, | ||
audience = null, | ||
issuer = null | ||
}) { | ||
if (!authUrl && !secretProvider) { | ||
@@ -114,10 +141,7 @@ throw new Error('`authUrl` is required'); | ||
const getUser = authUser({authUrl}), | ||
jwksClientOptions = { | ||
cache: true, | ||
rateLimit: true, // See: https://github.com/auth0/node-jwks-rsa#rate-limiting | ||
jwksRequestsPerMinute: 10, | ||
jwksUri: `${authUrl}/auth/${tenant}/.well-known/jwks.json` | ||
}, | ||
defaultSecretProvider = jwksClient.expressJwtSecret(jwksClientOptions); | ||
const getUser = authUser({authUrl}); | ||
const jwksClientOptions = { | ||
...defaultJwksClientOptions, | ||
jwksUri: `${authUrl}/auth/${tenant}/.well-known/jwks.json` | ||
}; | ||
@@ -156,7 +180,18 @@ // Attach authorization middleware to each non-public Socket.io event handler and Express HTTP route definition | ||
route.middleware.unshift( | ||
httpRS256({ | ||
secret: secretProvider || defaultSecretProvider, | ||
audience, | ||
issuer | ||
}), | ||
(req, res, next) => { | ||
expressRs256({ | ||
authUrl, | ||
tenant, | ||
secretProvider, | ||
audience, | ||
issuer | ||
})(req, res, (error) => { | ||
if (error) { | ||
res.status(401).send(error.message); | ||
return; | ||
} | ||
next(); | ||
}) | ||
}, | ||
authorizeJWT(route.scope) | ||
@@ -178,2 +213,5 @@ ); | ||
} | ||
}; | ||
} | ||
module.exports = authorize; | ||
module.exports.express = expressRs256; |
{ | ||
"name": "@labshare/services-auth", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "LabShare Services plugin for resource scope-based HTTP route and socket authorization", | ||
@@ -5,0 +5,0 @@ "main": "./", |
@@ -8,4 +8,4 @@ [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) | ||
`@labshare/services-auth` is a plugin that integrates with [@labshare/services](https://www.npmjs.com/package/@labshare/services) to | ||
provide Socket.io and Express.js API Resource Scope authorization with RS256 JWT validation. | ||
`@labshare/services-auth` is an Express.js middleware plugin that integrates with `Express.js` APIs to provide API | ||
Resource Scope authorization with RS256 JWT validation. | ||
@@ -30,5 +30,7 @@ ## Install | ||
### LabShare Services | ||
This example demonstrates scope-based authorization for an HTTP API module using `@labshare/services` to load the route definition. | ||
With the configuration below, only JWTs containing an audience of `https://my.api.identifier/resource` and a `read:users` scope | ||
would be allowed to access the API route. Additionally, the JWT would be validated using the JSON Web Key Set of the | ||
would be allowed to access the API route. Additionally, the JWT would be validated against the JSON Web Key Set of the | ||
specified LabShare Auth Tenant. | ||
@@ -54,3 +56,3 @@ | ||
```js | ||
// lib/index.js | ||
// index.js | ||
@@ -73,2 +75,23 @@ const {Services} = require('@labshare/services'); | ||
### Express.js | ||
The `@labshare/services-auth` module exports generic Express.js middleware for route authentication. | ||
```js | ||
// index.js | ||
const app = require('express')(); | ||
const servicesAuth = require('@labshare/services-auth'); | ||
// Adds route authentication to the Express.js routes | ||
app.use('/protected/*', servicesAuth.express({ | ||
authUrl: 'https://ls.auth.io/_api', | ||
audience: 'https://my.api.identifier/resource', | ||
issuer: 'LabShare Auth', | ||
tenant: 'my-tenant' | ||
})); | ||
app.listen(3000); | ||
``` | ||
## Development | ||
@@ -75,0 +98,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25350
448
102