@@ -18,25 +18,22 @@ const {
18
18
s3ProtocolEnforceRegion,
19
19
s3ProtocolAccessKeyId,
20
20
s3ProtocolAccessKeySecret,
21
+ s3ProtocolNonCanonicalHostHeader,
21
22
} = getConfig ( )
22
23
23
- export const signatureV4 = fastifyPlugin ( async function ( fastify : FastifyInstance ) {
24
- fastify . addHook ( 'preHandler' , async ( request : FastifyRequest ) => {
25
- if ( typeof request . headers . authorization !== 'string' ) {
26
- throw ERRORS . AccessDenied ( 'Missing authorization header' )
27
- }
24
+ type AWSRequest = FastifyRequest < { Querystring : { 'X-Amz-Credential' ?: string } } >
28
25
29
- const clientCredentials = SignatureV4 . parseAuthorizationHeader ( request . headers . authorization )
26
+ export const signatureV4 = fastifyPlugin ( async function ( fastify : FastifyInstance ) {
27
+ fastify . addHook ( 'preHandler' , async ( request : AWSRequest ) => {
28
+ const clientSignature = extractSignature ( request )
30
29
31
- const sessionToken = request . headers [ 'x-amz-security-token' ] as string | undefined
30
+ const sessionToken = clientSignature . sessionToken
32
31
33
32
const {
34
33
signature : signatureV4 ,
35
34
claims,
36
35
token,
37
- } = await createSignature ( request . tenantId , clientCredentials , {
38
- sessionToken : sessionToken ,
39
- } )
36
+ } = await createServerSignature ( request . tenantId , clientSignature )
40
37
41
38
const isVerified = signatureV4 . verify ( {
42
39
url : request . url ,
@@ -45,9 +42,7 @@ export const signatureV4 = fastifyPlugin(async function (fastify: FastifyInstanc
45
42
method : request . method ,
46
43
query : request . query as Record < string , string > ,
47
44
prefix : s3ProtocolPrefix ,
48
- credentials : clientCredentials . credentials ,
49
- signature : clientCredentials . signature ,
50
- signedHeaders : clientCredentials . signedHeaders ,
45
+ clientSignature : clientSignature ,
51
46
} )
52
47
53
48
if ( ! isVerified && ! sessionToken ) {
@@ -94,15 +89,23 @@ export const signatureV4 = fastifyPlugin(async function (fastify: FastifyInstanc
94
89
} )
95
90
} )
96
91
97
- async function createSignature (
98
- tenantId : string ,
99
- clientSignature : ClientSignature ,
100
- session ?: { sessionToken ?: string }
101
- ) {
92
+ function extractSignature ( req : AWSRequest ) {
93
+ if ( typeof req . headers . authorization === 'string' ) {
94
+ return SignatureV4 . parseAuthorizationHeader ( req . headers )
95
+ }
96
+
97
+ if ( typeof req . query [ 'X-Amz-Credential' ] === 'string' ) {
98
+ return SignatureV4 . parseQuerySignature ( req . query )
99
+ }
100
+
101
+ throw ERRORS . AccessDenied ( 'Missing signature' )
102
+ }
103
+
104
+ async function createServerSignature ( tenantId : string , clientSignature : ClientSignature ) {
102
105
const awsRegion = storageS3Region
103
106
const awsService = 's3'
104
107
105
- if ( session ?. sessionToken ) {
108
+ if ( clientSignature ?. sessionToken ) {
106
109
const tenantAnonKey = isMultitenant ? ( await getTenantConfig ( tenantId ) ) . anonKey : anonKey
107
110
108
111
if ( ! tenantAnonKey ) {
@@ -112,6 +115,7 @@ async function createSignature(
112
115
const signature = new SignatureV4 ( {
113
116
enforceRegion : s3ProtocolEnforceRegion ,
114
117
allowForwardedHeader : s3ProtocolAllowForwardedHeader ,
118
+ nonCanonicalForwardedHost : s3ProtocolNonCanonicalHostHeader ,
115
119
credentials : {
116
120
accessKey : tenantId ,
117
121
secretKey : tenantAnonKey ,
@@ -120,7 +124,7 @@ async function createSignature(
120
124
} ,
121
125
} )
122
126
123
- return { signature, claims : undefined , token : session . sessionToken }
127
+ return { signature, claims : undefined , token : clientSignature . sessionToken }
124
128
}
125
129
126
130
if ( isMultitenant ) {
@@ -132,6 +136,7 @@ async function createSignature(
132
136
const signature = new SignatureV4 ( {
133
137
enforceRegion : s3ProtocolEnforceRegion ,
134
138
allowForwardedHeader : s3ProtocolAllowForwardedHeader ,
139
+ nonCanonicalForwardedHost : s3ProtocolNonCanonicalHostHeader ,
135
140
credentials : {
136
141
accessKey : credential . accessKey ,
137
142
secretKey : credential . secretKey ,
@@ -152,6 +157,7 @@ async function createSignature(
152
157
const signature = new SignatureV4 ( {
153
158
enforceRegion : s3ProtocolEnforceRegion ,
154
159
allowForwardedHeader : s3ProtocolAllowForwardedHeader ,
160
+ nonCanonicalForwardedHost : s3ProtocolNonCanonicalHostHeader ,
155
161
credentials : {
156
162
accessKey : s3ProtocolAccessKeyId ,
157
163
secretKey : s3ProtocolAccessKeySecret ,
0 commit comments