@@ -10,6 +10,10 @@ $DELETE_VERB = "delete"
10
10
11
11
$API_VERSION = " 2018-12-31"
12
12
13
+ # Authorization headers are valid for 15 minutes
14
+ # https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key#specifying-the-date-header
15
+ $AUTHORIZATION_HEADER_REFRESH_THRESHOLD = [System.TimeSpan ]::FromMinutes(10 );
16
+
13
17
$MASTER_KEY_CACHE = @ {}
14
18
$SIGNATURE_HASH_CACHE = @ {}
15
19
$PARTITION_KEY_RANGE_CACHE = @ {}
@@ -141,13 +145,13 @@ Function Get-AuthorizationHeader([string]$ResourceGroup, [string]$SubscriptionId
141
145
142
146
Function Get-CommonHeaders ([string ]$now , [string ]$encodedAuthString , [string ]$contentType = " application/json" , [bool ]$isQuery = $false , [string ]$PartitionKey = $null , [string ]$Etag = $null ) {
143
147
$headers = @ {
144
- " x-ms-date" = $now ;
145
148
" x-ms-version" = $API_VERSION ;
146
- " Authorization" = $encodedAuthString ;
147
149
" Cache-Control" = " No-Cache" ;
148
150
" Content-Type" = $contentType ;
149
151
}
150
152
153
+ Set-AuthHeaders - headers $headers - now $now - encodedAuthString $encodedAuthString
154
+
151
155
if ($isQuery ) {
152
156
$headers [" x-ms-documentdb-isquery" ] = " true"
153
157
}
@@ -163,6 +167,16 @@ Function Get-CommonHeaders([string]$now, [string]$encodedAuthString, [string]$co
163
167
$headers
164
168
}
165
169
170
+ Function Set-AuthHeaders ($headers , [string ]$now , [string ]$encodedAuthString ) {
171
+ if ($now ) {
172
+ $headers [" x-ms-date" ] = $now
173
+ }
174
+
175
+ if ($encodedAuthString ) {
176
+ $headers [" Authorization" ] = $encodedAuthString
177
+ }
178
+ }
179
+
166
180
Function Get-QueryParametersAsNameValuePairs ($obj ) {
167
181
if (! $obj ) {
168
182
return @ ()
@@ -239,17 +253,28 @@ Function Get-ContinuationToken($response) {
239
253
}
240
254
}
241
255
242
- Function Invoke-CosmosDbApiRequestWithContinuation ([string ]$verb , [string ]$url , $headers , $body = $null ) {
256
+ Function Invoke-CosmosDbApiRequestWithContinuation ([string ]$verb , [string ]$url , $headers , [ ScriptBlock ] $refreshAuthHeaders , $body = $null ) {
243
257
# Remove in case the headers are reused between multiple calls to this function
244
258
$headers.Remove (" x-ms-continuation" );
245
259
260
+ $authHeaders = Invoke-Command - ScriptBlock $refreshAuthHeaders
261
+ Set-AuthHeaders - headers $headers - now $authHeaders.now - encodedAuthString $authHeaders.encodedAuthString
262
+
246
263
$response = Invoke-CosmosDbApiRequest - Verb $verb - Url $url - Body $body - Headers $headers
247
264
$response
248
265
249
266
$continuationToken = Get-ContinuationToken $response
250
267
while ($continuationToken ) {
251
268
$headers [" x-ms-continuation" ] = $continuationToken
252
269
270
+ $authHeaderReuseDisabled = $env: COSMOS_DB_FLAG_ENABLE_AUTH_HEADER_REUSE -eq 0
271
+ $authHeaderExpired = [System.DateTime ]::Parse($authHeaders.now ) + $AUTHORIZATION_HEADER_REFRESH_THRESHOLD -lt [System.DateTime ]::UtcNow
272
+
273
+ if ($authHeaderReuseDisabled -or $authHeaderExpired ) {
274
+ $authHeaders = Invoke-Command - ScriptBlock $refreshAuthHeaders
275
+ Set-AuthHeaders - headers $headers - now $authHeaders.now - encodedAuthString $authHeaders.encodedAuthString
276
+ }
277
+
253
278
$response = Invoke-CosmosDbApiRequest - Verb $verb - Url $url - Body $body - Headers $headers
254
279
$response
255
280
@@ -278,14 +303,17 @@ Function Get-PartitionKeyRangesOrError
278
303
return $cacheResult
279
304
}
280
305
281
- $now = Get-Time
282
-
283
- $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $GET_VERB - resourceType $PARTITIONKEYRANGE_TYPE - resourceUrl $collectionsUrl - now $now
306
+ $refreshAuthHeaders = {
307
+ $now = Get-Time
308
+ $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $GET_VERB - resourceType $PARTITIONKEYRANGE_TYPE - resourceUrl $collectionsUrl - now $now
284
309
285
- $headers = Get-CommonHeaders - now $now - encodedAuthString $encodedAuthString - PartitionKey $requestPartitionKey
310
+ return @ { now = $now ; encodedAuthString = $encodedAuthString }
311
+ }
312
+
313
+ $headers = Get-CommonHeaders - PartitionKey $requestPartitionKey
286
314
$headers [" x-ms-documentdb-query-enablecrosspartition" ] = " true"
287
315
288
- $response = Invoke-CosmosDbApiRequestWithContinuation - Verb $GET_VERB - Url $url - Headers $headers | Get-CosmosDbRecordContent
316
+ $response = Invoke-CosmosDbApiRequestWithContinuation - Verb $GET_VERB - Url $url - Headers $headers - RefreshAuthHeaders $refreshAuthHeaders | Get-CosmosDbRecordContent
289
317
290
318
$ranges = $response.partitionKeyRanges
291
319
@@ -450,16 +478,19 @@ Function Get-AllCosmosDbRecords(
450
478
451
479
$url = " $baseUrl /$docsUrl "
452
480
453
- $now = Get-Time
481
+ $refreshAuthHeaders = {
482
+ $now = Get-Time
483
+ $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $GET_VERB - resourceType $DOCS_TYPE - resourceUrl $collectionsUrl - now $now
454
484
455
- $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $GET_VERB - resourceType $DOCS_TYPE - resourceUrl $collectionsUrl - now $now
485
+ return @ { now = $now ; encodedAuthString = $encodedAuthString }
486
+ }
456
487
457
488
$tmp = $ProgressPreference
458
489
$ProgressPreference = ' SilentlyContinue'
459
490
try {
460
- $headers = Get-CommonHeaders - now $now - encodedAuthString $encodedAuthString - isQuery $true
491
+ $headers = Get-CommonHeaders - isQuery $true
461
492
462
- Invoke-CosmosDbApiRequestWithContinuation - verb $GET_VERB - url $url - Headers $headers
493
+ Invoke-CosmosDbApiRequestWithContinuation - verb $GET_VERB - url $url - Headers $headers - RefreshAuthHeaders $refreshAuthHeaders
463
494
}
464
495
catch {
465
496
Get-ExceptionResponseOrThrow $_
@@ -542,18 +573,21 @@ Function Search-CosmosDbRecords(
542
573
) {
543
574
$Parameters = @ (Get-QueryParametersAsNameValuePairs $Parameters )
544
575
576
+ if (! $DisableExtraFeatures ) {
577
+ return Search-CosmosDbRecordsWithExtraFeatures - ResourceGroup $ResourceGroup - Database $Database - Container $Container - Collection $Collection - Query $Query - Parameters $Parameters - SubscriptionId $SubscriptionId
578
+ }
579
+
545
580
$baseUrl = Get-BaseDatabaseUrl $Database
546
581
$collectionsUrl = Get-CollectionsUrl $Container $Collection
547
582
$docsUrl = " $collectionsUrl /$DOCS_TYPE "
548
583
549
584
$url = " $baseUrl /$docsUrl "
550
585
551
- $now = Get-Time
552
-
553
- $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $POST_VERB - resourceType $DOCS_TYPE - resourceUrl $collectionsUrl - now $now
586
+ $refreshAuthHeaders = {
587
+ $now = Get-Time
588
+ $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $POST_VERB - resourceType $DOCS_TYPE - resourceUrl $collectionsUrl - now $now
554
589
555
- if (! $DisableExtraFeatures ) {
556
- return Search-CosmosDbRecordsWithExtraFeatures - ResourceGroup $ResourceGroup - Database $Database - Container $Container - Collection $Collection - Query $Query - Parameters $Parameters - SubscriptionId $SubscriptionId
590
+ return @ { now = $now ; encodedAuthString = $encodedAuthString }
557
591
}
558
592
559
593
try {
@@ -562,10 +596,10 @@ Function Search-CosmosDbRecords(
562
596
parameters = $Parameters ;
563
597
}
564
598
565
- $headers = Get-CommonHeaders - now $now - encodedAuthString $encodedAuthString - isQuery $true - contentType " application/Query+json"
599
+ $headers = Get-CommonHeaders - isQuery $true - contentType " application/Query+json"
566
600
$headers [" x-ms-documentdb-query-enablecrosspartition" ] = " true"
567
601
568
- Invoke-CosmosDbApiRequestWithContinuation - verb $POST_VERB - url $url - Body $body - Headers $headers
602
+ Invoke-CosmosDbApiRequestWithContinuation - verb $POST_VERB - url $url - Body $body - Headers $headers - RefreshAuthHeaders $refreshAuthHeaders
569
603
}
570
604
catch {
571
605
Get-ExceptionResponseOrThrow $_
@@ -590,15 +624,18 @@ Function Search-CosmosDbRecordsWithExtraFeatures
590
624
591
625
$url = " $baseUrl /$docsUrl "
592
626
593
- $now = Get-Time
594
-
595
- $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $POST_VERB - resourceType $DOCS_TYPE - resourceUrl $collectionsUrl - now $now
596
-
597
627
$allPartitionKeyRangesOrError = Get-PartitionKeyRangesOrError - ResourceGroup $ResourceGroup - Database $Database - Container $Container - Collection $Collection - SubscriptionId $SubscriptionId
598
628
599
629
if ($allPartitionKeyRangesOrError.ErrorRecord ) {
600
630
return Get-ExceptionResponseOrThrow $allPartitionKeyRangesOrError.ErrorRecord
601
631
}
632
+
633
+ $refreshAuthHeaders = {
634
+ $now = Get-Time
635
+ $encodedAuthString = Get-AuthorizationHeader - ResourceGroup $ResourceGroup - SubscriptionId $SubscriptionId - Database $Database - verb $POST_VERB - resourceType $DOCS_TYPE - resourceUrl $collectionsUrl - now $now
636
+
637
+ return @ { now = $now ; encodedAuthString = $encodedAuthString }
638
+ }
602
639
603
640
try {
604
641
$ranges = $allPartitionKeyRangesOrError.Ranges
@@ -608,7 +645,8 @@ Function Search-CosmosDbRecordsWithExtraFeatures
608
645
parameters = $Parameters ;
609
646
}
610
647
611
- $headers = Get-CommonHeaders - now $now - encodedAuthString $encodedAuthString - isQuery $true - contentType " application/Query+json"
648
+ $authHeaders = Invoke-Command - ScriptBlock $refreshAuthHeaders
649
+ $headers = Get-CommonHeaders - now $authHeaders.now - encodedAuthString $authHeaders.encodedAuthString - isQuery $true - contentType " application/Query+json"
612
650
$headers += @ {
613
651
" x-ms-documentdb-query-enablecrosspartition" = " true" ;
614
652
" x-ms-cosmos-supported-query-features" = " NonValueAggregate, Aggregate, Distinct, MultipleOrderBy, OffsetAndLimit, OrderBy, Top, CompositeAggregate, GroupBy, MultipleAggregates" ;
@@ -640,7 +678,7 @@ Function Search-CosmosDbRecordsWithExtraFeatures
640
678
foreach ($partitionKeyRange in $partitionKeyRanges ) {
641
679
$headers [" x-ms-documentdb-partitionkeyrangeid" ] = $partitionKeyRange.id
642
680
643
- Invoke-CosmosDbApiRequestWithContinuation - verb $POST_VERB - url $url - Body $body - Headers $headers
681
+ Invoke-CosmosDbApiRequestWithContinuation - verb $POST_VERB - url $url - Body $body - Headers $headers - RefreshAuthHeaders $refreshAuthHeaders
644
682
}
645
683
}
646
684
catch {
@@ -966,7 +1004,8 @@ Function Use-CosmosDbInternalFlag
966
1004
(
967
1005
$enableFiddlerDebugging = $null ,
968
1006
$enableCaching = $null ,
969
- $enablePartitionKeyRangeSearches = $null
1007
+ $enablePartitionKeyRangeSearches = $null ,
1008
+ $enableAuthHeaderReuse = $null
970
1009
) {
971
1010
if ($null -ne $enableFiddlerDebugging ) {
972
1011
$env: AZURE_CLI_DISABLE_CONNECTION_VERIFICATION = if ($enableFiddlerDebugging ) { 1 } else { 0 }
@@ -979,6 +1018,10 @@ Function Use-CosmosDbInternalFlag
979
1018
if ($null -ne $enablePartitionKeyRangeSearches ) {
980
1019
$env: COSMOS_DB_FLAG_ENABLE_PARTITION_KEY_RANGE_SEARCHES = if ($enablePartitionKeyRangeSearches ) { 1 } else { 0 }
981
1020
}
1021
+
1022
+ if ($null -ne $enableAuthHeaderReuse ) {
1023
+ $env: COSMOS_DB_FLAG_ENABLE_AUTH_HEADER_REUSE = if ($enableAuthHeaderReuse ) { 1 } else { 0 }
1024
+ }
982
1025
}
983
1026
984
1027
Function Use-CosmosDbReadonlyKeys
0 commit comments