Skip to content

Commit

Permalink
Fix ArgumentOutOfRangeException when token has default ExpiresOn value (
Browse files Browse the repository at this point in the history
  • Loading branch information
christothes authored Nov 11, 2024
1 parent d9e0d05 commit bd68205
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

### Bugs Fixed

- Fixed an issue where `BearerTokenAuthenticationPolicy` throws `ArgumentOutOfRangeException` if the `ExpiresOn` property of the token is the default value. ([#47040](https://github.com/Azure/azure-sdk-for-net/pull/47040))

### Other Changes

- Use `BinaryData.Empty` for `PipelineResponse.Content` when HTTP message has no content.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,14 @@ private async ValueTask SetResultOnTcsFromCredentialAsync(TokenRequestContext co
? await _credential.GetTokenAsync(context, cancellationToken).ConfigureAwait(false)
: _credential.GetToken(context, cancellationToken);

targetTcs.SetResult(new AuthHeaderValueInfo("Bearer " + token.Token, token.ExpiresOn, token.RefreshOn.HasValue ? token.RefreshOn.Value : token.ExpiresOn - _tokenRefreshOffset));
DateTimeOffset refreshOn = token.RefreshOn.HasValue switch
{
true => token.RefreshOn.Value,
false when _tokenRefreshOffset.Ticks > token.ExpiresOn.Ticks => token.ExpiresOn,
_ => token.ExpiresOn - _tokenRefreshOffset
};

targetTcs.SetResult(new AuthHeaderValueInfo("Bearer " + token.Token, token.ExpiresOn, refreshOn));
}

internal readonly struct AuthHeaderValueInfo
Expand Down
24 changes: 24 additions & 0 deletions sdk/core/Azure.Core/tests/BearerTokenAuthenticationPolicyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,30 @@ public async Task BearerTokenAuthenticationPolicy_RequestsTokenEveryRequest()
Assert.AreEqual("Bearer token2", auth2Value);
}

[Test]
public async Task BearerTokenAuthenticationPolicy_RequestsTokenEveryRequest_InvalidExpiresOn()
{
var accessTokens = new Queue<AccessToken>();
accessTokens.Enqueue(new AccessToken("token1", default));
accessTokens.Enqueue(new AccessToken("token2", default));

var credential = new TokenCredentialStub(
(r, c) => r.Scopes.SequenceEqual(new[] { "scope1", "scope2" }) ? accessTokens.Dequeue() : default,
IsAsync);

var policy = new BearerTokenAuthenticationPolicy(credential, new[] { "scope1", "scope2" });
MockTransport transport = CreateMockTransport(new MockResponse(200), new MockResponse(200));

await SendGetRequest(transport, policy, uri: new Uri("https://example.com"));
await SendGetRequest(transport, policy, uri: new Uri("https://example.com"));

Assert.True(transport.Requests[0].Headers.TryGetValue("Authorization", out string auth1Value));
Assert.True(transport.Requests[1].Headers.TryGetValue("Authorization", out string auth2Value));

Assert.AreEqual("Bearer token1", auth1Value);
Assert.AreEqual("Bearer token2", auth2Value);
}

[Test]
public async Task BearerTokenAuthenticationPolicy_CachesHeaderValue()
{
Expand Down

0 comments on commit bd68205

Please sign in to comment.