Skip to content

Commit 7de6e06

Browse files
authored
CosmosDB: AAD auth related fix (#22478)
* Add the missing auth context when creating the barrier related requests.
1 parent d5f58b6 commit 7de6e06

File tree

2 files changed

+88
-3
lines changed

2 files changed

+88
-3
lines changed

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelper.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ public static Mono<RxDocumentServiceRequest> createAsync(
3939

4040
AuthorizationTokenType originalRequestTokenType = request.authorizationTokenType;
4141

42+
if (authorizationTokenProvider != null && authorizationTokenProvider.getAuthorizationTokenType() != null) {
43+
originalRequestTokenType = authorizationTokenProvider.getAuthorizationTokenType();
44+
}
45+
4246
if (originalRequestTokenType == AuthorizationTokenType.Invalid) {
4347
String message = "AuthorizationTokenType not set for the read request";
4448
assert false : message;
@@ -53,7 +57,8 @@ public static Mono<RxDocumentServiceRequest> createAsync(
5357
OperationType.HeadFeed,
5458
null,
5559
ResourceType.Database,
56-
null);
60+
null,
61+
originalRequestTokenType);
5762
} else if (request.getIsNameBased()) {
5863
// Name based server request
5964

@@ -63,13 +68,16 @@ public static Mono<RxDocumentServiceRequest> createAsync(
6368
barrierLsnRequest = RxDocumentServiceRequest.createFromName(clientContext,
6469
OperationType.Head,
6570
collectionLink,
66-
ResourceType.DocumentCollection);
71+
ResourceType.DocumentCollection,
72+
originalRequestTokenType);
6773
} else {
6874
// RID based Server request
6975
barrierLsnRequest = RxDocumentServiceRequest.create(clientContext,
7076
OperationType.Head,
7177
ResourceId.parse(request.getResourceId()).getDocumentCollectionId().toString(),
72-
ResourceType.DocumentCollection, null);
78+
ResourceType.DocumentCollection,
79+
null,
80+
originalRequestTokenType);
7381
}
7482

7583
barrierLsnRequest.getHeaders().put(HttpConstants.HttpHeaders.X_DATE, Utils.nowAsRFC1123());

sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelperTest.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33

44
package com.azure.cosmos.implementation.directconnectivity;
55

6+
import com.azure.core.credential.AccessToken;
7+
import com.azure.core.credential.TokenCredential;
8+
import com.azure.core.credential.TokenRequestContext;
69
import com.azure.cosmos.implementation.AsyncDocumentClient;
10+
import com.azure.cosmos.implementation.AuthorizationTokenType;
11+
import com.azure.cosmos.implementation.Configs;
712
import com.azure.cosmos.implementation.Document;
813
import com.azure.cosmos.implementation.HttpConstants;
914
import com.azure.cosmos.implementation.IAuthorizationTokenProvider;
@@ -12,10 +17,16 @@
1217
import com.azure.cosmos.implementation.RxDocumentClientImpl;
1318
import com.azure.cosmos.implementation.RxDocumentServiceRequest;
1419
import com.azure.cosmos.implementation.TestConfigurations;
20+
import com.azure.cosmos.implementation.Utils;
1521
import com.azure.cosmos.implementation.routing.PartitionKeyRangeIdentity;
1622
import org.testng.annotations.DataProvider;
1723
import org.testng.annotations.Test;
24+
import reactor.core.publisher.Mono;
1825

26+
import java.net.URI;
27+
import java.net.URISyntaxException;
28+
import java.time.OffsetDateTime;
29+
import java.time.ZonedDateTime;
1930
import java.util.Map;
2031
import java.util.UUID;
2132

@@ -143,6 +154,41 @@ public void barrierDocumentReadRidBasedRequest() {
143154
assertThat(barrierRequest.getIsNameBased()).isEqualTo(false);
144155
}
145156

157+
@Test(groups = "direct")
158+
public void barrierWithAadAuthorizationTokenProviderType() throws URISyntaxException {
159+
160+
TokenCredential tokenCredential = new AadSimpleTokenCredential(TestConfigurations.MASTER_KEY);
161+
162+
IAuthorizationTokenProvider authTokenProvider = new RxDocumentClientImpl(new URI(TestConfigurations.HOST),
163+
null,
164+
null,
165+
null,
166+
null,
167+
new Configs(),
168+
null,
169+
null,
170+
tokenCredential,
171+
false,
172+
false,
173+
false,
174+
null);
175+
176+
ResourceType resourceType = ResourceType.DocumentCollection;
177+
OperationType operationType = OperationType.Read;
178+
179+
Document randomResource = new Document();
180+
randomResource.setId(UUID.randomUUID().toString());
181+
RxDocumentServiceRequest request =
182+
RxDocumentServiceRequest.create(mockDiagnosticsClientContext(), operationType, resourceType, "/dbs/7mVFAA==/colls/7mVFAP1jpeU=", randomResource, (Map<String, String>) null);
183+
184+
RxDocumentServiceRequest barrierRequest = BarrierRequestHelper.createAsync(mockDiagnosticsClientContext(), request, authTokenProvider, 11l, 10l).block();
185+
186+
assertThat(authTokenProvider.getAuthorizationTokenType()).isEqualTo(AuthorizationTokenType.AadToken);
187+
assertThat(barrierRequest.authorizationTokenType).isEqualTo(AuthorizationTokenType.AadToken);
188+
assertThat(request.authorizationTokenType).isEqualTo(AuthorizationTokenType.PrimaryMasterKey);
189+
}
190+
191+
146192
@DataProvider(name = "isCollectionHeadBarrierRequestArgProvider")
147193
public Object[][] isCollectionHeadBarrierRequestArgProvider() {
148194
return new Object[][]{
@@ -214,5 +260,36 @@ private Long getTargetLsn(RxDocumentServiceRequest req) {
214260
private Long getTargetGlobalLsn(RxDocumentServiceRequest req) {
215261
return Long.parseLong(getHeaderValue(req, HttpConstants.HttpHeaders.TARGET_GLOBAL_COMMITTED_LSN));
216262
}
263+
264+
class AadSimpleTokenCredential implements TokenCredential {
265+
private final String keyEncoded;
266+
private final String AAD_HEADER_COSMOS_EMULATOR = "{\"typ\":\"JWT\",\"alg\":\"RS256\",\"x5t\":\"CosmosEmulatorPrimaryMaster\",\"kid\":\"CosmosEmulatorPrimaryMaster\"}";
267+
private final String AAD_CLAIM_COSMOS_EMULATOR_FORMAT = "{\"aud\":\"https://localhost.localhost\",\"iss\":\"https://sts.fake-issuer.net/7b1999a1-dfd7-440e-8204-00170979b984\",\"iat\":%d,\"nbf\":%d,\"exp\":%d,\"aio\":\"\",\"appid\":\"localhost\",\"appidacr\":\"1\",\"idp\":\"https://localhost:8081/\",\"oid\":\"96313034-4739-43cb-93cd-74193adbe5b6\",\"rh\":\"\",\"sub\":\"localhost\",\"tid\":\"EmulatorFederation\",\"uti\":\"\",\"ver\":\"1.0\",\"scp\":\"user_impersonation\",\"groups\":[\"7ce1d003-4cb3-4879-b7c5-74062a35c66e\",\"e99ff30c-c229-4c67-ab29-30a6aebc3e58\",\"5549bb62-c77b-4305-bda9-9ec66b85d9e4\",\"c44fd685-5c58-452c-aaf7-13ce75184f65\",\"be895215-eab5-43b7-9536-9ef8fe130330\"]}";
268+
269+
public AadSimpleTokenCredential(String emulatorKey) {
270+
if (emulatorKey == null || emulatorKey.isEmpty()) {
271+
throw new IllegalArgumentException("emulatorKey");
272+
}
273+
274+
this.keyEncoded = Utils.encodeUrlBase64String(emulatorKey.getBytes());
275+
}
276+
277+
@Override
278+
public Mono<AccessToken> getToken(TokenRequestContext tokenRequestContext) {
279+
String aadToken = emulatorKey_based_AAD_String();
280+
return Mono.just(new AccessToken(aadToken, OffsetDateTime.now().plusHours(2)));
281+
}
282+
283+
String emulatorKey_based_AAD_String() {
284+
ZonedDateTime currentTime = ZonedDateTime.now();
285+
String part1Encoded = Utils.encodeUrlBase64String(AAD_HEADER_COSMOS_EMULATOR.getBytes());
286+
String part2 = String.format(AAD_CLAIM_COSMOS_EMULATOR_FORMAT,
287+
currentTime.toEpochSecond(),
288+
currentTime.toEpochSecond(),
289+
currentTime.plusHours(2).toEpochSecond());
290+
String part2Encoded = Utils.encodeUrlBase64String(part2.getBytes());
291+
return part1Encoded + "." + part2Encoded + "." + this.keyEncoded;
292+
}
293+
}
217294
}
218295

0 commit comments

Comments
 (0)