Skip to content

Commit cadebaa

Browse files
committed
Lower log level to Debug; add forceRefresh cache bypass test
Changed log statements in AuthenticationService from Information to Debug to reduce log verbosity. Added a unit test to ensure forceRefresh bypasses the token cache in MicrosoftGraphTokenProvider.
1 parent abd2a63 commit cadebaa

2 files changed

Lines changed: 41 additions & 7 deletions

File tree

src/Microsoft.Agents.A365.DevTools.Cli/Services/AuthenticationService.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,14 @@ public async Task<string> GetAccessTokenAsync(
124124
}
125125
else
126126
{
127-
_logger.LogInformation("Using cached authentication token for {ResourceUrl} (tenant: {TenantId})",
127+
_logger.LogDebug("Using cached authentication token for {ResourceUrl} (tenant: {TenantId})",
128128
resourceUrl, tenantId);
129129
return cachedToken.AccessToken;
130130
}
131131
}
132132
else
133133
{
134-
_logger.LogInformation("Using cached authentication token for {ResourceUrl}", resourceUrl);
134+
_logger.LogDebug("Using cached authentication token for {ResourceUrl}", resourceUrl);
135135
return cachedToken.AccessToken;
136136
}
137137
}
@@ -187,8 +187,8 @@ private async Task<TokenInfo> AuthenticateInteractivelyAsync(
187187
// This creates the format required by Azure AD for the TokenRequestContext: {resourceAppId}/{scope}
188188
// Example: "ea9ffc3e-8a23-4a7d-836d-234d7c7565c1/McpServers.Mail.All"
189189
scopes = explicitScopes.Select(s => $"{resourceUrl}/{s}").ToArray();
190-
_logger.LogInformation("Using explicit scopes for authentication: {Scopes}", string.Join(", ", explicitScopes));
191-
_logger.LogInformation("Formatted as: {FormattedScopes}", string.Join(", ", scopes));
190+
_logger.LogDebug("Using explicit scopes for authentication: {Scopes}", string.Join(", ", explicitScopes));
191+
_logger.LogDebug("Formatted as: {FormattedScopes}", string.Join(", ", scopes));
192192
}
193193
else
194194
{
@@ -225,13 +225,13 @@ private async Task<TokenInfo> AuthenticateInteractivelyAsync(
225225
scope = resourceUrl.EndsWith("/.default", StringComparison.OrdinalIgnoreCase)
226226
? resourceUrl
227227
: $"{resourceUrl}/.default";
228-
_logger.LogInformation("Using custom resource for authentication: {Resource}", resourceUrl);
228+
_logger.LogDebug("Using custom resource for authentication: {Resource}", resourceUrl);
229229
}
230230
scopes = [scope];
231-
_logger.LogInformation($"Token scope: {scope}");
231+
_logger.LogDebug("Token scope: {Scope}", scope);
232232
}
233233

234-
_logger.LogInformation("Authenticating for tenant: {TenantId}", effectiveTenantId);
234+
_logger.LogDebug("Authenticating for tenant: {TenantId}", effectiveTenantId);
235235

236236
// Use provided client ID or default to PowerShell client ID
237237
effectiveClientId = string.IsNullOrWhiteSpace(clientId)

src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/MicrosoftGraphTokenProviderTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,4 +348,38 @@ public async Task GetMgGraphAccessTokenAsync_EscapesSingleQuotesInClientAppId()
348348
// Assert
349349
token.Should().Be(expectedToken);
350350
}
351+
352+
[Fact]
353+
public async Task GetMgGraphAccessTokenAsync_WithForceRefresh_BypassesCache()
354+
{
355+
// Arrange
356+
var tenantId = "12345678-1234-1234-1234-123456789abc";
357+
var scopes = new[] { "AgentIdentityBlueprint.DeleteRestore.All" };
358+
var clientAppId = "87654321-4321-4321-4321-cba987654321";
359+
// Valid JWT with a future exp claim (year 2099)
360+
var msalToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzZWxsYWsiLCJleHAiOjQwNzA5MDg4MDB9.signature";
361+
var callCount = 0;
362+
363+
var provider = new MicrosoftGraphTokenProvider(_executor, _logger)
364+
{
365+
MsalTokenAcquirerOverride = (_, _, _, _) =>
366+
{
367+
callCount++;
368+
return Task.FromResult<string?>(msalToken);
369+
}
370+
};
371+
372+
// Prime the cache with a first call
373+
await provider.GetMgGraphAccessTokenAsync(tenantId, scopes, false, clientAppId);
374+
callCount.Should().Be(1);
375+
376+
// Act — second call with forceRefresh: true should bypass the cache
377+
var token = await provider.GetMgGraphAccessTokenAsync(tenantId, scopes, false, clientAppId, forceRefresh: true);
378+
379+
// Assert
380+
token.Should().Be(msalToken);
381+
callCount.Should().Be(2,
382+
because: "forceRefresh: true must evict the cached token and re-invoke MSAL, " +
383+
"ensuring a stale CAE-revoked token is not reused");
384+
}
351385
}

0 commit comments

Comments
 (0)