Skip to content

Commit

Permalink
feat: add passportJwtSecret support
Browse files Browse the repository at this point in the history
  • Loading branch information
MeStrak committed Feb 11, 2022
1 parent 43d7487 commit 4f2627a
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 13 deletions.
38 changes: 28 additions & 10 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,25 @@ _ Note that even though the `AUTH_CONFIG_SECRET` is not necessarily a secret (in

The provided configuration is very similar to the NestJS passport-jwt example with a few modifications:
- it must be provided as a JSON string containing a `config` property which is an array of valid passport-jwt configurations
- the jwtFromRequest which tells passport-jwt where to find the JWT in the request (usually the `Authorization` header) function must be deconstructed into an object containing funcName and args properties
- the `jwtFromRequest` function which tells passport-jwt where to find the JWT in the request (usually the `Authorization` header) function must be deconstructed into an object containing funcName and args properties
- `passportJwtSecret` function should not be written in the configuration file, only the arguments are required in the `passportJwtSecret` object

### Examples

This is an example for multiple passport JWT configurations as they would be configured in Javascript.

```js
[{
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`,
jwksUri: "https://auth.issuer.com",
}),

jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: process.env.AUTH0_AUDIENCE,
issuer: `${process.env.AUTH0_DOMAIN}/`,
audience: 'MY_APP_AUDIENCE',
issuer: `https://auth.issuer.com/`,
algorithms: ['RS256'],
},
{
Expand All @@ -36,25 +41,38 @@ The provided configuration is very similar to the NestJS passport-jwt example wi
secretOrKey: 'APPX_SECRET_KEY',
},
{
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
jwtFromRequest: ExtractJwt.fromBodyField('USER_JWT'),
ignoreExpiration: false,
secretOrKey: 'APPY_SECRET_KEY',
}]
```

And an example env file configuration for `AUTH_CONFIG_SECRET` based on the configuration above.

```bash
AUTH_CONFIG_SECRET =
# note that in a .env file this should be formatted onto one line - it is shown multiline here for easier readability
# see project example.env file for a single line config
{"config":[{
"jwtFromRequest":{
"funcName": "fromAuthHeaderAsBearerToken"},
"secretOrKeyProvider": {
"cache": true,
"rateLimit": true,
"jwksRequestsPerMinute": 5,
"jwksUri": "https://uri.com"
},
"jwtFromRequest":{"funcName": "fromAuthHeaderAsBearerToken"},
"audience": "MY_APP_AUDIENCE",
"issuer":"https://auth.issuer.com/",
"algorithms": ['RS256']
}
{
"jwtFromRequest":{"funcName": "fromAuthHeaderAsBearerToken"},
"ignoreExpiration":false,
"secretOrKey":"APPX_SECRET_KEY"},
{"jwtFromRequest": {
"funcName": "fromAuthHeaderAsBearerToken"},
{
"jwtFromRequest": {"funcName": "fromBodyField", args: 'USER_JWT'},
"ignoreExpiration":false,
"secretOrKey":"another_secret_key"}
"secretOrKey":"APPY_SECRET_KEY"}
]
}
```
Expand Down
137 changes: 135 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"haiku-random": "1.0.0",
"ioredis": "4.28.2",
"joi": "17.5.0",
"jwks-rsa": "^2.0.5",
"lodash": "4.17.21",
"mongoose": "5.13.13",
"mongoose-cast-aggregation": "0.2.1",
Expand Down
6 changes: 5 additions & 1 deletion src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as fs from 'fs';
import { Agent } from 'http';
import * as tunnel from 'tunnel';
import { ExtractJwt } from '@mestrak/passport-multi-jwt';
import { passportJwtSecret } from 'jwks-rsa';
import validationSchema from './environmentValidationSchema';

@Injectable()
Expand Down Expand Up @@ -108,9 +109,12 @@ export class ConfigService {
getAuthConfig(): any {
const authConfig = this.get('AUTH_CONFIG_SECRET');

// as jwtExtractor is a function, translate function name string to function call
//patch in ExtractJwt and passportJwtSecret function calls as they cannot be enocded in JSON
return authConfig.config.map((configuration) => ({
...configuration,
...(configuration.secretOrKeyProvider
? { secretOrKeyProvider: passportJwtSecret(configuration.secretOrKeyProvider) }
: {}),
jwtFromRequest: ExtractJwt[configuration.jwtFromRequest.funcName](configuration.jwtFromRequest.args),
}));
}
Expand Down

0 comments on commit 4f2627a

Please sign in to comment.