Skip to content

Commit

Permalink
Azure Active Directory: Fixes issue with using wrong scope value (#1984)
Browse files Browse the repository at this point in the history
* Fix endpoint host

* Adds tests

* Adds null checks

* Fixed test
  • Loading branch information
j82w committed Nov 5, 2020
1 parent 9e22964 commit fc187c4
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ internal sealed class AuthorizationTokenProviderTokenCredential : AuthorizationT

public AuthorizationTokenProviderTokenCredential(
TokenCredential tokenCredential,
string accountEndpointHost,
Uri accountEndpoint,
TimeSpan requestTimeout,
TimeSpan? backgroundTokenCredentialRefreshInterval)
{
this.tokenCredentialCache = new TokenCredentialCache(
tokenCredential: tokenCredential,
accountEndpointHost: accountEndpointHost,
accountEndpoint: accountEndpoint,
requestTimeout: requestTimeout,
backgroundTokenCredentialRefreshInterval: backgroundTokenCredentialRefreshInterval);
}
Expand Down
12 changes: 9 additions & 3 deletions Microsoft.Azure.Cosmos/src/Authorization/TokenCredentialCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,20 @@ internal sealed class TokenCredentialCache : IDisposable

internal TokenCredentialCache(
TokenCredential tokenCredential,
string accountEndpointHost,
Uri accountEndpoint,
TimeSpan requestTimeout,
TimeSpan? backgroundTokenCredentialRefreshInterval)
{
this.tokenCredential = tokenCredential;
this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential));

if (accountEndpoint == null)
{
throw new ArgumentNullException(nameof(accountEndpoint));
}

this.tokenRequestContext = new TokenRequestContext(new string[]
{
string.Format(TokenCredentialCache.ScopeFormat, accountEndpointHost)
string.Format(TokenCredentialCache.ScopeFormat, accountEndpoint.Host)
});

if (requestTimeout <= TimeSpan.Zero)
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Azure.Cosmos/src/CosmosClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public CosmosClient(
this.Endpoint = new Uri(accountEndpoint);
this.AuthorizationTokenProvider = new AuthorizationTokenProviderTokenCredential(
tokenCredential,
accountEndpoint,
this.Endpoint,
clientOptions.RequestTimeout,
clientOptions.TokenCredentialBackgroundRefreshInterval);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using global::Azure.Core;
using IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;

public class LocalEmulatorTokenCredential : TokenCredential
{
Expand Down Expand Up @@ -39,6 +41,9 @@ public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext request

private AccessToken GetAccessToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
// Verify that the request context is a valid URI
Assert.AreEqual("https://127.0.0.1/.default", requestContext.Scopes.First());

this.GetTokenCallback?.Invoke(
requestContext,
cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ namespace Microsoft.Azure.Cosmos.Tests
[TestClass]
public class CosmosAuthorizationTests
{
private static readonly Uri AccountEndpoint = new Uri("https://test-account.documents.azure.com");
private const string ExpectedScope = "https://test-account.documents.azure.com/.default";

private readonly AccessToken AccessToken = new AccessToken("AccessToken", DateTimeOffset.MaxValue);


public CosmosAuthorizationTests()
{
}
Expand Down Expand Up @@ -79,7 +85,7 @@ public async Task TokenAuthAsync()

using AuthorizationTokenProvider cosmosAuthorization = new AuthorizationTokenProviderTokenCredential(
simpleEmulatorTokenCredential,
"https://localhost:8081",
new Uri("https://127.0.0.1:8081"),
requestTimeout: TimeSpan.FromSeconds(30),
backgroundTokenCredentialRefreshInterval: TimeSpan.FromSeconds(1));

Expand Down Expand Up @@ -137,7 +143,7 @@ public void TestTokenCredentialCacheMaxAndMinValues()
TimeSpan toLarge = TimeSpan.MaxValue - TimeSpan.FromMilliseconds(1);
new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: toLarge);
Assert.Fail("Should throw ArgumentException");
Expand All @@ -151,7 +157,7 @@ public void TestTokenCredentialCacheMaxAndMinValues()
{
new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: TimeSpan.MinValue);
Assert.Fail("Should throw ArgumentException");
Expand All @@ -165,7 +171,7 @@ public void TestTokenCredentialCacheMaxAndMinValues()
{
new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: TimeSpan.Zero);
Assert.Fail("Should throw ArgumentException");
Expand All @@ -179,7 +185,7 @@ public void TestTokenCredentialCacheMaxAndMinValues()
{
new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: TimeSpan.FromMilliseconds(-1));
Assert.Fail("Should throw ArgumentException");
Expand All @@ -193,7 +199,7 @@ public void TestTokenCredentialCacheMaxAndMinValues()
{
new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.MinValue,
backgroundTokenCredentialRefreshInterval: TimeSpan.FromMinutes(1));
Assert.Fail("Should throw ArgumentException");
Expand All @@ -207,7 +213,7 @@ public void TestTokenCredentialCacheMaxAndMinValues()
{
new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.Zero,
backgroundTokenCredentialRefreshInterval: TimeSpan.FromMinutes(1));
Assert.Fail("Should throw ArgumentException");
Expand All @@ -220,22 +226,17 @@ public void TestTokenCredentialCacheMaxAndMinValues()
// Which is roughly 24 days
using TokenCredentialCache token = new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: TimeSpan.FromMilliseconds(Int32.MaxValue));

using TokenCredentialCache disableBackgroundTask = new TokenCredentialCache(
new Mock<TokenCredential>().Object,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: TimeSpan.MaxValue);
}

private const string AccountEndpointHost = "test-account.documents.azure.com";
private const string ExpectedScope = "https://test-account.documents.azure.com/.default";

private readonly AccessToken AccessToken = new AccessToken("AccessToken", DateTimeOffset.MaxValue);

[TestMethod]
public async Task TestTokenCredentialCacheHappyPathAsync()
{
Expand Down Expand Up @@ -440,7 +441,7 @@ private TokenCredentialCache CreateTokenCredentialCache(
{
return new TokenCredentialCache(
tokenCredential,
CosmosAuthorizationTests.AccountEndpointHost,
CosmosAuthorizationTests.AccountEndpoint,
requestTimeout: requestTimeout ?? TimeSpan.FromSeconds(15),
backgroundTokenCredentialRefreshInterval: TimeSpan.FromSeconds(5));
}
Expand Down

0 comments on commit fc187c4

Please sign in to comment.