Skip to content

Commit a5158a4

Browse files
authored
feat: Introduce header to override authorizer response (#1328)
1 parent e217fcb commit a5158a4

File tree

7 files changed

+189
-6
lines changed

7 files changed

+189
-6
lines changed

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,11 @@ only enabled with the `--ignoreJWTSignature` flag. Make sure to only set this fl
364364

365365
You are able to use some custom headers in your request to gain more control over the requestContext object.
366366

367-
| Header | Event key |
368-
| ------------------------------- | ----------------------------------------------------------- |
369-
| cognito-identity-id | event.requestContext.identity.cognitoIdentityId |
370-
| cognito-authentication-provider | event.requestContext.identity.cognitoAuthenticationProvider |
367+
| Header | Event key | Example |
368+
| ------------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------- |
369+
| cognito-identity-id | event.requestContext.identity.cognitoIdentityId | |
370+
| cognito-authentication-provider | event.requestContext.identity.cognitoAuthenticationProvider | |
371+
| sls-offline-authorizer-override | event.requestContext.authorizer | { "iam": {"cognitoUser": { "amr": ["unauthenticated"], "identityId": "abc123" }}} |
371372

372373
By doing this you are now able to change those values using a custom header. This can help you with easier authentication or retrieving the userId from a `cognitoAuthenticationProvider` value.
373374

@@ -744,6 +745,10 @@ We try to follow [Airbnb's JavaScript Style Guide](https://github.com/airbnb/jav
744745
| :------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------: |
745746
| [lteacher](https://github.com/lteacher) | [martinmicunda](https://github.com/martinmicunda) | [nori3tsu](https://github.com/nori3tsu) | [ppasmanik](https://github.com/ppasmanik) | [ryanzyy](https://github.com/ryanzyy) |
746747
747-
| [<img alt="m0ppers" src="https://avatars3.githubusercontent.com/u/819421?v=4&s=117" width="117">](https://github.com/m0ppers) | [<img alt="footballencarta" src="https://avatars0.githubusercontent.com/u/1312258?v=4&s=117" width="117">](https://github.com/footballencarta) | [<img alt="bryanvaz" src="https://avatars0.githubusercontent.com/u/9157498?v=4&s=117" width="117">](https://github.com/bryanvaz) | [<img alt="njyjn" src="https://avatars.githubusercontent.com/u/10694375?v=4&s=117" width="117">](https://github.com/njyjn) |
748+
| [<img alt="m0ppers" src="https://avatars3.githubusercontent.com/u/819421?v=4&s=117" width="117">](https://github.com/m0ppers) | [<img alt="footballencarta" src="https://avatars0.githubusercontent.com/u/1312258?v=4&s=117" width="117">](https://github.com/footballencarta) | [<img alt="bryanvaz" src="https://avatars0.githubusercontent.com/u/9157498?v=4&s=117" width="117">](https://github.com/bryanvaz) | [<img alt="njyjn" src="https://avatars.githubusercontent.com/u/10694375?v=4&s=117" width="117">](https://github.com/njyjn) | |
748749
| :---------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------: | ------------------------------------- |
749750
| [m0ppers](https://github.com/m0ppers) | [footballencarta](https://github.com/footballencarta) | [bryanvaz](https://github.com/bryanvaz) | [njyjn](https://github.com/njyjn) | [kdybicz](https://github.com/kdybicz) |
751+
752+
| [<img alt="ericctsf" src="https://avatars.githubusercontent.com/u/42775388?s=400&v=4" width="117">](https://github.com/ericctsf) | | | | |
753+
| :------------------------------------------------------------------------------------------------------------------------------: | :-: | :-: | :-: | :-: |
754+
| [ericctsf](https://github.com/erictsf) | | | | |

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@
156156
"Dima Krutolianov (https://github.com/dimadk24)",
157157
"Bryan Vaz (https://github.com/bryanvaz)",
158158
"Justin Ng (https://github.com/njyjn)",
159-
"Fernando Alvarez (https://github.com/jefer590)"
159+
"Fernando Alvarez (https://github.com/jefer590)",
160+
"Eric Carter (https://github.com/ericctsf)"
160161
],
161162
"husky": {
162163
"hooks": {

src/events/http/lambda-events/LambdaProxyIntegrationEvent.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ export default class LambdaProxyIntegrationEvent {
8585
// NOTE FIXME request.raw.req.rawHeaders can only be null for testing (hapi shot inject())
8686
const headers = parseHeaders(rawHeaders || []) || {}
8787

88+
if (headers['sls-offline-authorizer-override']) {
89+
try {
90+
authAuthorizer = parse(headers['sls-offline-authorizer-override'])
91+
} catch (error) {
92+
if (this.log) {
93+
this.log.error(
94+
'Could not parse header sls-offline-authorizer-override, make sure it is correct JSON',
95+
)
96+
} else {
97+
console.error(
98+
'Serverless-offline: Could not parse header sls-offline-authorizer-override make sure it is correct JSON.',
99+
)
100+
}
101+
}
102+
}
103+
88104
if (body) {
89105
if (typeof body !== 'string') {
90106
// this.#request.payload is NOT the same as the rawPayload

src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,22 @@ export default class LambdaProxyIntegrationEventV2 {
7272
// NOTE FIXME request.raw.req.rawHeaders can only be null for testing (hapi shot inject())
7373
const headers = parseHeaders(rawHeaders || []) || {}
7474

75+
if (headers['sls-offline-authorizer-override']) {
76+
try {
77+
authAuthorizer = parse(headers['sls-offline-authorizer-override'])
78+
} catch (error) {
79+
if (this.log) {
80+
this.log.error(
81+
'Could not parse header sls-offline-authorizer-override, make sure it is correct JSON',
82+
)
83+
} else {
84+
console.error(
85+
'Serverless-offline: Could not parse header sls-offline-authorizer-override make sure it is correct JSON.',
86+
)
87+
}
88+
}
89+
}
90+
7591
if (body) {
7692
if (typeof body !== 'string') {
7793
// this.#request.payload is NOT the same as the rawPayload
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict'
2+
3+
exports.echo_authorizer = async function get(context) {
4+
return {
5+
body: JSON.stringify(context.requestContext.authorizer),
6+
statusCode: 200,
7+
}
8+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { resolve } from 'path'
2+
import fetch from 'node-fetch'
3+
import { joinUrl, setup, teardown } from '../_testHelpers/index.js'
4+
5+
jest.setTimeout(30000)
6+
7+
const envAuthorizer = {
8+
iam: {
9+
cognitoUser: {
10+
amr: ['unauthenticated'],
11+
identityId: 'env_identity_id',
12+
},
13+
},
14+
}
15+
16+
const headerAuthorizer = {
17+
iam: {
18+
cognitoUser: {
19+
amr: ['unauthenticated'],
20+
identityId: 'header_identity_id',
21+
},
22+
},
23+
}
24+
25+
describe('override authorizer tests', () => {
26+
// init
27+
beforeAll(async () => {
28+
process.env.AUTHORIZER = JSON.stringify(envAuthorizer)
29+
await setup({
30+
servicePath: resolve(__dirname),
31+
})
32+
})
33+
34+
// cleanup
35+
afterAll(async () => {
36+
process.env.AUTHORIZER = undefined
37+
await teardown()
38+
})
39+
40+
//
41+
;[
42+
{
43+
description: 'HTTP API Falls back on env variable',
44+
req: {
45+
path: '/gateway_v2_http_api',
46+
headers: {},
47+
},
48+
res: {
49+
status: 200,
50+
body: envAuthorizer,
51+
},
52+
},
53+
{
54+
description: 'REST API Falls back on env variable',
55+
req: {
56+
path: '/dev/gateway_v1_rest_api',
57+
headers: {},
58+
},
59+
res: {
60+
status: 200,
61+
body: envAuthorizer,
62+
},
63+
},
64+
{
65+
description: 'HTTP API uses override header',
66+
req: {
67+
path: '/gateway_v2_http_api',
68+
headers: {
69+
'sls-offline-authorizer-override': JSON.stringify(headerAuthorizer),
70+
},
71+
},
72+
res: {
73+
status: 200,
74+
body: headerAuthorizer,
75+
},
76+
},
77+
{
78+
description: 'HTTP API uses override header',
79+
req: {
80+
path: '/dev/gateway_v1_rest_api',
81+
headers: {
82+
'sls-offline-authorizer-override': JSON.stringify(headerAuthorizer),
83+
},
84+
},
85+
res: {
86+
status: 200,
87+
body: headerAuthorizer,
88+
},
89+
},
90+
].forEach(({ description, req, res }) => {
91+
test(description, async () => {
92+
const url = joinUrl(TEST_BASE_URL, req.path)
93+
const options = {
94+
headers: req.headers,
95+
}
96+
97+
const response = await fetch(url, options)
98+
expect(response.status).toEqual(res.status)
99+
100+
const json = await response.json()
101+
expect(json).toEqual(res.body)
102+
})
103+
})
104+
})
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
service: jwt-authorizer
2+
3+
plugins:
4+
- ../../../
5+
6+
custom:
7+
serverless-offline:
8+
noAuth: true
9+
10+
provider:
11+
memorySize: 128
12+
name: aws
13+
region: us-east-1 # default
14+
runtime: nodejs12.x
15+
stage: dev
16+
versionFunctions: false
17+
httpApi:
18+
payload: '2.0'
19+
20+
functions:
21+
user:
22+
events:
23+
- http:
24+
authorizer:
25+
type: 'AWS_IAM'
26+
method: get
27+
path: gateway_v1_rest_api
28+
- httpApi:
29+
authorizer:
30+
type: AWS_IAM
31+
method: get
32+
path: gateway_v2_http_api
33+
handler: handler.echo_authorizer

0 commit comments

Comments
 (0)