Skip to content

Commit 272902e

Browse files
committed
TokenCredentialCache: Adds an options to override AAD audience scope. (#5252)
# Pull Request Template ## Description Add AAD audience scope override functionality when this environment variable is set AADScopeOverride = "AZURE_COSMOS_AAD_SCOPE_OVERRIDE". If no environment variable is et then it uses the existing default scope value. This will help clients in accessing applications which have a different scope. ## Type of change Please delete options that are not relevant. - [X] New feature (non-breaking change which adds functionality) ## Closing issues To automatically close an issue: closes #IssueNumber
1 parent 79a11bf commit 272902e

5 files changed

Lines changed: 101 additions & 27 deletions

File tree

Microsoft.Azure.Cosmos/src/Authorization/TokenCredentialCache.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ internal sealed class TokenCredentialCache : IDisposable
3535
// The token refresh retries half the time. Given default of 1hr it will retry at 30m, 15, 7.5, 3.75, 1.875
3636
// If the background refresh fails with less than a minute then just allow the request to hit the exception.
3737
public static readonly TimeSpan MinimumTimeBetweenBackgroundRefreshInterval = TimeSpan.FromMinutes(1);
38-
38+
3939
private const string ScopeFormat = "https://{0}/.default";
40+
4041
private readonly TokenRequestContext tokenRequestContext;
4142
private readonly TokenCredential tokenCredential;
4243
private readonly CancellationTokenSource cancellationTokenSource;
@@ -62,13 +63,17 @@ internal TokenCredentialCache(
6263
if (accountEndpoint == null)
6364
{
6465
throw new ArgumentNullException(nameof(accountEndpoint));
65-
}
66-
67-
this.tokenRequestContext = new TokenRequestContext(new string[]
68-
{
69-
string.Format(TokenCredentialCache.ScopeFormat, accountEndpoint.Host)
70-
});
71-
66+
}
67+
68+
string? scopeOverride = ConfigurationManager.AADScopeOverrideValue(defaultValue: null);
69+
70+
this.tokenRequestContext = new TokenRequestContext(new string[]
71+
{
72+
!string.IsNullOrEmpty(scopeOverride)
73+
? scopeOverride
74+
: string.Format(TokenCredentialCache.ScopeFormat, accountEndpoint.Host)
75+
});
76+
7277
if (backgroundTokenCredentialRefreshInterval.HasValue)
7378
{
7479
if (backgroundTokenCredentialRefreshInterval.Value <= TimeSpan.Zero)

Microsoft.Azure.Cosmos/src/Util/ConfigurationManager.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ internal static class ConfigurationManager
4343
/// <summary>
4444
/// Environment variable name to enable thin client mode.
4545
/// </summary>
46-
internal static readonly string ThinClientModeEnabled = "AZURE_COSMOS_THIN_CLIENT_ENABLED";
46+
internal static readonly string ThinClientModeEnabled = "AZURE_COSMOS_THIN_CLIENT_ENABLED";
47+
48+
/// <summary>
49+
/// Environment variable to override AAD scope.
50+
/// </summary>
51+
internal static readonly string AADScopeOverride = "AZURE_COSMOS_AAD_SCOPE_OVERRIDE";
4752

4853
/// <summary>
4954
/// A read-only string containing the environment variable name for capturing the consecutive failure count for reads, before triggering per partition
@@ -183,6 +188,20 @@ public static bool IsThinClientEnabled(
183188
.GetEnvironmentVariable(
184189
variable: ConfigurationManager.ThinClientModeEnabled,
185190
defaultValue: defaultValue);
191+
}
192+
193+
/// <summary>
194+
/// Gets the AAD scope value to override.
195+
/// </summary>
196+
/// <param name="defaultValue">Emoty string for AAD scope if no scope value is provided.</param>
197+
/// <returns>AAD scope value.</returns>
198+
public static string AADScopeOverrideValue(
199+
string defaultValue)
200+
{
201+
return ConfigurationManager
202+
.GetEnvironmentVariable(
203+
variable: ConfigurationManager.AADScopeOverride,
204+
defaultValue: defaultValue);
186205
}
187206

188207
/// <summary>

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAadTests.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public async Task AadMockTest(ConnectionMode connectionMode)
3838
try
3939
{
4040
(string endpoint, string authKey) = TestCommon.GetAccountInfo();
41-
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(authKey);
41+
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(expectedScope: "https://127.0.0.1/.default", masterKey: authKey);
4242
CosmosClientOptions clientOptions = new CosmosClientOptions()
4343
{
4444
ConnectionMode = connectionMode,
@@ -140,8 +140,9 @@ void GetAadTokenCallBack(
140140

141141
(string endpoint, string authKey) = TestCommon.GetAccountInfo();
142142
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(
143-
authKey,
144-
GetAadTokenCallBack);
143+
expectedScope: "https://127.0.0.1/.default",
144+
masterKey: authKey,
145+
getTokenCallback: GetAadTokenCallBack);
145146

146147
CosmosClientOptions clientOptions = new CosmosClientOptions()
147148
{
@@ -191,8 +192,9 @@ void GetAadTokenCallBack(
191192

192193
(string endpoint, string authKey) = TestCommon.GetAccountInfo();
193194
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(
194-
authKey,
195-
GetAadTokenCallBack);
195+
expectedScope: "https://127.0.0.1/.default",
196+
masterKey: authKey,
197+
getTokenCallback: GetAadTokenCallBack);
196198

197199
CosmosClientOptions clientOptions = new CosmosClientOptions()
198200
{
@@ -232,8 +234,9 @@ void GetAadTokenCallBack(
232234

233235
(string endpoint, string authKey) = TestCommon.GetAccountInfo();
234236
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(
235-
authKey,
236-
GetAadTokenCallBack);
237+
expectedScope: "https://127.0.0.1/.default",
238+
masterKey: authKey,
239+
getTokenCallback: GetAadTokenCallBack);
237240

238241
CosmosClientOptions clientOptions = new CosmosClientOptions()
239242
{

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/LocalEmulatorTokenCredential.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ public class LocalEmulatorTokenCredential : TokenCredential
1818
private readonly DateTime? DefaultDateTime = null;
1919
private readonly Action<TokenRequestContext, CancellationToken> GetTokenCallback;
2020
private readonly string masterKey;
21+
private readonly string expectedScope;
2122

22-
internal LocalEmulatorTokenCredential(
23+
internal LocalEmulatorTokenCredential(
24+
string expectedScope,
2325
string masterKey = null,
2426
Action<TokenRequestContext, CancellationToken> getTokenCallback = null,
2527
DateTime? defaultDateTime = null)
2628
{
2729
this.masterKey = masterKey;
2830
this.GetTokenCallback = getTokenCallback;
29-
this.DefaultDateTime = defaultDateTime;
31+
this.DefaultDateTime = defaultDateTime;
32+
this.expectedScope = expectedScope;
3033
}
3134

3235
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
@@ -40,9 +43,8 @@ public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext request
4043
}
4144

4245
private AccessToken GetAccessToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
43-
{
44-
// Verify that the request context is a valid URI
45-
Assert.AreEqual("https://127.0.0.1/.default", requestContext.Scopes.First());
46+
{
47+
Assert.AreEqual(this.expectedScope, requestContext.Scopes.First());
4648

4749
this.GetTokenCallback?.Invoke(
4850
requestContext,

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosAuthorizationTests.cs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ public async Task ResourceTokenAsync()
8484
[TestMethod]
8585
public async Task TokenAuthAsync()
8686
{
87-
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(
88-
"VGhpcyBpcyBhIHNhbXBsZSBzdHJpbmc=",
87+
LocalEmulatorTokenCredential simpleEmulatorTokenCredential = new LocalEmulatorTokenCredential(
88+
expectedScope: "https://127.0.0.1/.default",
89+
masterKey: "VGhpcyBpcyBhIHNhbXBsZSBzdHJpbmc=",
8990
defaultDateTime: new DateTime(2030, 9, 21, 9, 9, 9, DateTimeKind.Utc));
9091

9192
using AuthorizationTokenProvider cosmosAuthorization = new AuthorizationTokenProviderTokenCredential(
@@ -103,7 +104,7 @@ public async Task TokenAuthAsync()
103104
AuthorizationTokenType.PrimaryMasterKey);
104105

105106
Assert.AreEqual(
106-
"type%3daad%26ver%3d1.0%26sig%3dew0KICAgICAgICAgICAgICAgICJhbGciOiJSUzI1NiIsDQogICAgICAgICAgICAgICAgImtpZCI6InhfOUtTdXNLVTVZY0hmNCIsDQogICAgICAgICAgICAgICAgInR5cCI6IkpXVCINCiAgICAgICAgICAgIH0.ew0KICAgICAgICAgICAgICAgICJvaWQiOiI5NjMxMzAzNC00NzM5LTQzY2ItOTNjZC03NDE5M2FkYmU1YjYiLA0KICAgICAgICAgICAgICAgICJ0aWQiOiI3YjE5OTlhMS1kZmQ3LTQ0MGUtODIwNC0wMDE3MDk3OWI5ODQiLA0KICAgICAgICAgICAgICAgICJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLA0KICAgICAgICAgICAgICAgICJncm91cHMiOlsNCiAgICAgICAgICAgICAgICAgICAgIjdjZTFkMDAzLTRjYjMtNDg3OS1iN2M1LTc0MDYyYTM1YzY2ZSIsDQogICAgICAgICAgICAgICAgICAgICJlOTlmZjMwYy1jMjI5LTRjNjctYWIyOS0zMGE2YWViYzNlNTgiLA0KICAgICAgICAgICAgICAgICAgICAiNTU0OWJiNjItYzc3Yi00MzA1LWJkYTktOWVjNjZiODVkOWU0IiwNCiAgICAgICAgICAgICAgICAgICAgImM0NGZkNjg1LTVjNTgtNDUyYy1hYWY3LTEzY2U3NTE4NGY2NSIsDQogICAgICAgICAgICAgICAgICAgICJiZTg5NTIxNS1lYWI1LTQzYjctOTUzNi05ZWY4ZmUxMzAzMzAiDQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAibmJmIjoxOTE2MjEyMTQ5LA0KICAgICAgICAgICAgICAgICJleHAiOjE5MTYyMTU3NDksDQogICAgICAgICAgICAgICAgImlhdCI6MTU5NjU5MjMzNSwNCiAgICAgICAgICAgICAgICAiaXNzIjoiaHR0cHM6Ly9zdHMuZmFrZS1pc3N1ZXIubmV0LzdiMTk5OWExLWRmZDctNDQwZS04MjA0LTAwMTcwOTc5Yjk4NCIsDQogICAgICAgICAgICAgICAgImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LmxvY2FsaG9zdCINCiAgICAgICAgICAgIH0.VkdocGN5QnBjeUJoSUhOaGJYQnNaU0J6ZEhKcGJtYz0",
107+
"type%3daad%26ver%3d1.0%26sig%3dewogICAgICAgICAgICAgICAgImFsZyI6IlJTMjU2IiwKICAgICAgICAgICAgICAgICJraWQiOiJ4XzlLU3VzS1U1WWNIZjQiLAogICAgICAgICAgICAgICAgInR5cCI6IkpXVCIKICAgICAgICAgICAgfQ.ewogICAgICAgICAgICAgICAgIm9pZCI6Ijk2MzEzMDM0LTQ3MzktNDNjYi05M2NkLTc0MTkzYWRiZTViNiIsCiAgICAgICAgICAgICAgICAidGlkIjoiN2IxOTk5YTEtZGZkNy00NDBlLTgyMDQtMDAxNzA5NzliOTg0IiwKICAgICAgICAgICAgICAgICJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLAogICAgICAgICAgICAgICAgImdyb3VwcyI6WwogICAgICAgICAgICAgICAgICAgICI3Y2UxZDAwMy00Y2IzLTQ4NzktYjdjNS03NDA2MmEzNWM2NmUiLAogICAgICAgICAgICAgICAgICAgICJlOTlmZjMwYy1jMjI5LTRjNjctYWIyOS0zMGE2YWViYzNlNTgiLAogICAgICAgICAgICAgICAgICAgICI1NTQ5YmI2Mi1jNzdiLTQzMDUtYmRhOS05ZWM2NmI4NWQ5ZTQiLAogICAgICAgICAgICAgICAgICAgICJjNDRmZDY4NS01YzU4LTQ1MmMtYWFmNy0xM2NlNzUxODRmNjUiLAogICAgICAgICAgICAgICAgICAgICJiZTg5NTIxNS1lYWI1LTQzYjctOTUzNi05ZWY4ZmUxMzAzMzAiCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgIm5iZiI6MTkxNjIxMjE0OSwKICAgICAgICAgICAgICAgICJleHAiOjE5MTYyMTU3NDksCiAgICAgICAgICAgICAgICAiaWF0IjoxNTk2NTkyMzM1LAogICAgICAgICAgICAgICAgImlzcyI6Imh0dHBzOi8vc3RzLmZha2UtaXNzdWVyLm5ldC83YjE5OTlhMS1kZmQ3LTQ0MGUtODIwNC0wMDE3MDk3OWI5ODQiLAogICAgICAgICAgICAgICAgImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LmxvY2FsaG9zdCIKICAgICAgICAgICAgfQ.VkdocGN5QnBjeUJoSUhOaGJYQnNaU0J6ZEhKcGJtYz0",
107108
token);
108109
Assert.IsNull(payload);
109110
}
@@ -118,7 +119,7 @@ public async Task TokenAuthAsync()
118119
AuthorizationTokenType.PrimaryMasterKey);
119120

120121
Assert.AreEqual(
121-
"type%3daad%26ver%3d1.0%26sig%3dew0KICAgICAgICAgICAgICAgICJhbGciOiJSUzI1NiIsDQogICAgICAgICAgICAgICAgImtpZCI6InhfOUtTdXNLVTVZY0hmNCIsDQogICAgICAgICAgICAgICAgInR5cCI6IkpXVCINCiAgICAgICAgICAgIH0.ew0KICAgICAgICAgICAgICAgICJvaWQiOiI5NjMxMzAzNC00NzM5LTQzY2ItOTNjZC03NDE5M2FkYmU1YjYiLA0KICAgICAgICAgICAgICAgICJ0aWQiOiI3YjE5OTlhMS1kZmQ3LTQ0MGUtODIwNC0wMDE3MDk3OWI5ODQiLA0KICAgICAgICAgICAgICAgICJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLA0KICAgICAgICAgICAgICAgICJncm91cHMiOlsNCiAgICAgICAgICAgICAgICAgICAgIjdjZTFkMDAzLTRjYjMtNDg3OS1iN2M1LTc0MDYyYTM1YzY2ZSIsDQogICAgICAgICAgICAgICAgICAgICJlOTlmZjMwYy1jMjI5LTRjNjctYWIyOS0zMGE2YWViYzNlNTgiLA0KICAgICAgICAgICAgICAgICAgICAiNTU0OWJiNjItYzc3Yi00MzA1LWJkYTktOWVjNjZiODVkOWU0IiwNCiAgICAgICAgICAgICAgICAgICAgImM0NGZkNjg1LTVjNTgtNDUyYy1hYWY3LTEzY2U3NTE4NGY2NSIsDQogICAgICAgICAgICAgICAgICAgICJiZTg5NTIxNS1lYWI1LTQzYjctOTUzNi05ZWY4ZmUxMzAzMzAiDQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAibmJmIjoxOTE2MjEyMTQ5LA0KICAgICAgICAgICAgICAgICJleHAiOjE5MTYyMTU3NDksDQogICAgICAgICAgICAgICAgImlhdCI6MTU5NjU5MjMzNSwNCiAgICAgICAgICAgICAgICAiaXNzIjoiaHR0cHM6Ly9zdHMuZmFrZS1pc3N1ZXIubmV0LzdiMTk5OWExLWRmZDctNDQwZS04MjA0LTAwMTcwOTc5Yjk4NCIsDQogICAgICAgICAgICAgICAgImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LmxvY2FsaG9zdCINCiAgICAgICAgICAgIH0.VkdocGN5QnBjeUJoSUhOaGJYQnNaU0J6ZEhKcGJtYz0", token);
122+
"type%3daad%26ver%3d1.0%26sig%3dewogICAgICAgICAgICAgICAgImFsZyI6IlJTMjU2IiwKICAgICAgICAgICAgICAgICJraWQiOiJ4XzlLU3VzS1U1WWNIZjQiLAogICAgICAgICAgICAgICAgInR5cCI6IkpXVCIKICAgICAgICAgICAgfQ.ewogICAgICAgICAgICAgICAgIm9pZCI6Ijk2MzEzMDM0LTQ3MzktNDNjYi05M2NkLTc0MTkzYWRiZTViNiIsCiAgICAgICAgICAgICAgICAidGlkIjoiN2IxOTk5YTEtZGZkNy00NDBlLTgyMDQtMDAxNzA5NzliOTg0IiwKICAgICAgICAgICAgICAgICJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLAogICAgICAgICAgICAgICAgImdyb3VwcyI6WwogICAgICAgICAgICAgICAgICAgICI3Y2UxZDAwMy00Y2IzLTQ4NzktYjdjNS03NDA2MmEzNWM2NmUiLAogICAgICAgICAgICAgICAgICAgICJlOTlmZjMwYy1jMjI5LTRjNjctYWIyOS0zMGE2YWViYzNlNTgiLAogICAgICAgICAgICAgICAgICAgICI1NTQ5YmI2Mi1jNzdiLTQzMDUtYmRhOS05ZWM2NmI4NWQ5ZTQiLAogICAgICAgICAgICAgICAgICAgICJjNDRmZDY4NS01YzU4LTQ1MmMtYWFmNy0xM2NlNzUxODRmNjUiLAogICAgICAgICAgICAgICAgICAgICJiZTg5NTIxNS1lYWI1LTQzYjctOTUzNi05ZWY4ZmUxMzAzMzAiCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgIm5iZiI6MTkxNjIxMjE0OSwKICAgICAgICAgICAgICAgICJleHAiOjE5MTYyMTU3NDksCiAgICAgICAgICAgICAgICAiaWF0IjoxNTk2NTkyMzM1LAogICAgICAgICAgICAgICAgImlzcyI6Imh0dHBzOi8vc3RzLmZha2UtaXNzdWVyLm5ldC83YjE5OTlhMS1kZmQ3LTQ0MGUtODIwNC0wMDE3MDk3OWI5ODQiLAogICAgICAgICAgICAgICAgImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LmxvY2FsaG9zdCIKICAgICAgICAgICAgfQ.VkdocGN5QnBjeUJoSUhOaGJYQnNaU0J6ZEhKcGJtYz0", token);
122123
Assert.IsNull(payload);
123124
}
124125

@@ -132,10 +133,54 @@ public async Task TokenAuthAsync()
132133
AuthorizationTokenType.PrimaryMasterKey);
133134

134135
Assert.AreEqual(
135-
"type%3daad%26ver%3d1.0%26sig%3dew0KICAgICAgICAgICAgICAgICJhbGciOiJSUzI1NiIsDQogICAgICAgICAgICAgICAgImtpZCI6InhfOUtTdXNLVTVZY0hmNCIsDQogICAgICAgICAgICAgICAgInR5cCI6IkpXVCINCiAgICAgICAgICAgIH0.ew0KICAgICAgICAgICAgICAgICJvaWQiOiI5NjMxMzAzNC00NzM5LTQzY2ItOTNjZC03NDE5M2FkYmU1YjYiLA0KICAgICAgICAgICAgICAgICJ0aWQiOiI3YjE5OTlhMS1kZmQ3LTQ0MGUtODIwNC0wMDE3MDk3OWI5ODQiLA0KICAgICAgICAgICAgICAgICJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLA0KICAgICAgICAgICAgICAgICJncm91cHMiOlsNCiAgICAgICAgICAgICAgICAgICAgIjdjZTFkMDAzLTRjYjMtNDg3OS1iN2M1LTc0MDYyYTM1YzY2ZSIsDQogICAgICAgICAgICAgICAgICAgICJlOTlmZjMwYy1jMjI5LTRjNjctYWIyOS0zMGE2YWViYzNlNTgiLA0KICAgICAgICAgICAgICAgICAgICAiNTU0OWJiNjItYzc3Yi00MzA1LWJkYTktOWVjNjZiODVkOWU0IiwNCiAgICAgICAgICAgICAgICAgICAgImM0NGZkNjg1LTVjNTgtNDUyYy1hYWY3LTEzY2U3NTE4NGY2NSIsDQogICAgICAgICAgICAgICAgICAgICJiZTg5NTIxNS1lYWI1LTQzYjctOTUzNi05ZWY4ZmUxMzAzMzAiDQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAibmJmIjoxOTE2MjEyMTQ5LA0KICAgICAgICAgICAgICAgICJleHAiOjE5MTYyMTU3NDksDQogICAgICAgICAgICAgICAgImlhdCI6MTU5NjU5MjMzNSwNCiAgICAgICAgICAgICAgICAiaXNzIjoiaHR0cHM6Ly9zdHMuZmFrZS1pc3N1ZXIubmV0LzdiMTk5OWExLWRmZDctNDQwZS04MjA0LTAwMTcwOTc5Yjk4NCIsDQogICAgICAgICAgICAgICAgImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LmxvY2FsaG9zdCINCiAgICAgICAgICAgIH0.VkdocGN5QnBjeUJoSUhOaGJYQnNaU0J6ZEhKcGJtYz0", token);
136+
"type%3daad%26ver%3d1.0%26sig%3dewogICAgICAgICAgICAgICAgImFsZyI6IlJTMjU2IiwKICAgICAgICAgICAgICAgICJraWQiOiJ4XzlLU3VzS1U1WWNIZjQiLAogICAgICAgICAgICAgICAgInR5cCI6IkpXVCIKICAgICAgICAgICAgfQ.ewogICAgICAgICAgICAgICAgIm9pZCI6Ijk2MzEzMDM0LTQ3MzktNDNjYi05M2NkLTc0MTkzYWRiZTViNiIsCiAgICAgICAgICAgICAgICAidGlkIjoiN2IxOTk5YTEtZGZkNy00NDBlLTgyMDQtMDAxNzA5NzliOTg0IiwKICAgICAgICAgICAgICAgICJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLAogICAgICAgICAgICAgICAgImdyb3VwcyI6WwogICAgICAgICAgICAgICAgICAgICI3Y2UxZDAwMy00Y2IzLTQ4NzktYjdjNS03NDA2MmEzNWM2NmUiLAogICAgICAgICAgICAgICAgICAgICJlOTlmZjMwYy1jMjI5LTRjNjctYWIyOS0zMGE2YWViYzNlNTgiLAogICAgICAgICAgICAgICAgICAgICI1NTQ5YmI2Mi1jNzdiLTQzMDUtYmRhOS05ZWM2NmI4NWQ5ZTQiLAogICAgICAgICAgICAgICAgICAgICJjNDRmZDY4NS01YzU4LTQ1MmMtYWFmNy0xM2NlNzUxODRmNjUiLAogICAgICAgICAgICAgICAgICAgICJiZTg5NTIxNS1lYWI1LTQzYjctOTUzNi05ZWY4ZmUxMzAzMzAiCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgIm5iZiI6MTkxNjIxMjE0OSwKICAgICAgICAgICAgICAgICJleHAiOjE5MTYyMTU3NDksCiAgICAgICAgICAgICAgICAiaWF0IjoxNTk2NTkyMzM1LAogICAgICAgICAgICAgICAgImlzcyI6Imh0dHBzOi8vc3RzLmZha2UtaXNzdWVyLm5ldC83YjE5OTlhMS1kZmQ3LTQ0MGUtODIwNC0wMDE3MDk3OWI5ODQiLAogICAgICAgICAgICAgICAgImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LmxvY2FsaG9zdCIKICAgICAgICAgICAgfQ.VkdocGN5QnBjeUJoSUhOaGJYQnNaU0J6ZEhKcGJtYz0", token);
136137
Assert.IsNull(payload);
137138
}
138-
}
139+
}
140+
141+
[DataTestMethod]
142+
[DataRow("https://env-override/.default", "https://env-override/.default", DisplayName = "EnvVarOverride")]
143+
[DataRow("https://cosmos.azure.com/.default", "https://cosmos.azure.com/.default", DisplayName = "EnvVarOverride_Fabric")]
144+
[DataRow(null, "https://anyhost.documents.azure.com/.default", DisplayName = "NoEnvVar_DefaultScope")]
145+
public async Task TokenCredentialCache_SetsCorrectScope_EnvOverrideOrDefault(string envVarValue, string expectedScope)
146+
{
147+
Environment.SetEnvironmentVariable("AZURE_COSMOS_AAD_SCOPE_OVERRIDE", envVarValue);
148+
149+
try
150+
{
151+
string anyHost = "anyhost.documents.azure.com";
152+
Uri anyUri = new Uri($"https://{anyHost}");
153+
154+
LocalEmulatorTokenCredential credential = new LocalEmulatorTokenCredential(
155+
masterKey: "testkey",
156+
expectedScope: expectedScope);
157+
158+
using (AuthorizationTokenProvider authorization = new AuthorizationTokenProviderTokenCredential(
159+
credential,
160+
anyUri,
161+
backgroundTokenCredentialRefreshInterval: TimeSpan.FromSeconds(1)))
162+
{
163+
StoreResponseNameValueCollection headers = new StoreResponseNameValueCollection();
164+
(string token, string payload) = await authorization.GetUserAuthorizationAsync(
165+
"dbs\\test",
166+
ResourceType.Database.ToResourceTypeString(),
167+
"GET",
168+
headers,
169+
AuthorizationTokenType.PrimaryMasterKey);
170+
171+
Assert.IsFalse(string.IsNullOrEmpty(token));
172+
Assert.IsNull(payload);
173+
}
174+
}
175+
catch (Exception ex)
176+
{
177+
Assert.Fail($"Test failed with exception: {ex}");
178+
}
179+
finally
180+
{
181+
Environment.SetEnvironmentVariable("AZURE_COSMOS_AAD_SCOPE_OVERRIDE", null);
182+
}
183+
}
139184

140185
[TestMethod]
141186
public void TestTokenCredentialCacheMaxAndMinValues()

0 commit comments

Comments
 (0)