Skip to content

Commit fcec87b

Browse files
pr comments
1 parent 0e66794 commit fcec87b

File tree

3 files changed

+57
-12
lines changed

3 files changed

+57
-12
lines changed

src/client/Microsoft.Identity.Client/ApiConfig/Parameters/AcquireTokenForClientParameters.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public void LogParameters(ILoggerAdapter logger)
2626
builder.AppendLine("=== AcquireTokenForClientParameters ===");
2727
builder.AppendLine("SendX5C: " + SendX5C);
2828
builder.AppendLine("ForceRefresh: " + ForceRefresh);
29+
builder.AppendLine($"AccessTokenHashToRefresh: {!string.IsNullOrEmpty(AccessTokenHashToRefresh)}");
2930
logger.Info(builder.ToString());
3031
}
3132
}

src/client/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ private async Task<AuthenticationResult> SendTokenRequestToAppTokenProviderAsync
202202
return authResult;
203203
}
204204

205+
/// <summary>
206+
/// Checks if the token should be used from the cache.
207+
/// </summary>
208+
/// <returns></returns>
205209
private async Task<MsalAccessTokenCacheItem> GetCachedAccessTokenAsync()
206210
{
207211
// Fetch the cache item (could be null if none found).
@@ -219,6 +223,11 @@ private async Task<MsalAccessTokenCacheItem> GetCachedAccessTokenAsync()
219223
return cacheItem;
220224
}
221225

226+
/// <summary>
227+
/// Checks if the token should be used from the cache.
228+
/// </summary>
229+
/// <param name="cacheItem"></param>
230+
/// <returns></returns>
222231
private bool ShouldUseCachedToken(MsalAccessTokenCacheItem cacheItem)
223232
{
224233
// 1) No cached item
@@ -239,18 +248,32 @@ private bool ShouldUseCachedToken(MsalAccessTokenCacheItem cacheItem)
239248
return true;
240249
}
241250

251+
/// <summary>
252+
/// Checks if the token hash matches the hash provided in AccessTokenHashToRefresh.
253+
/// </summary>
254+
/// <param name="tokenSecret"></param>
255+
/// <param name="accessTokenHashToRefresh"></param>
256+
/// <returns></returns>
242257
private bool IsMatchingTokenHash(string tokenSecret, string accessTokenHashToRefresh)
243258
{
244259
string cachedTokenHash = _cryptoManager.CreateSha256Hash(tokenSecret);
245260
return string.Equals(cachedTokenHash, accessTokenHashToRefresh, StringComparison.Ordinal);
246261
}
247262

263+
/// <summary>
264+
/// Marks the request as a cache hit and increments the cache hit count.
265+
/// </summary>
248266
private void MarkAccessTokenAsCacheHit()
249267
{
250268
AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true;
251269
Metrics.IncrementTotalAccessTokensFromCache();
252270
}
253271

272+
/// <summary>
273+
/// returns the cached access token item
274+
/// </summary>
275+
/// <param name="cachedAccessTokenItem"></param>
276+
/// <returns></returns>
254277
private AuthenticationResult CreateAuthenticationResultFromCache(MsalAccessTokenCacheItem cachedAccessTokenItem)
255278
{
256279
AuthenticationResult authResult = new AuthenticationResult(
@@ -266,6 +289,11 @@ private AuthenticationResult CreateAuthenticationResultFromCache(MsalAccessToken
266289
return authResult;
267290
}
268291

292+
/// <summary>
293+
/// Gets overriden scopes for client credentials flow
294+
/// </summary>
295+
/// <param name="inputScopes"></param>
296+
/// <returns></returns>
269297
protected override SortedSet<string> GetOverriddenScopes(ISet<string> inputScopes)
270298
{
271299
// Client credentials should not add the reserved scopes
@@ -274,6 +302,10 @@ protected override SortedSet<string> GetOverriddenScopes(ISet<string> inputScope
274302
return new SortedSet<string>(inputScopes);
275303
}
276304

305+
/// <summary>
306+
/// Gets the body parameters for the client credentials flow
307+
/// </summary>
308+
/// <returns></returns>
277309
private Dictionary<string, string> GetBodyParameters()
278310
{
279311
var dict = new Dictionary<string, string>
@@ -285,6 +317,11 @@ private Dictionary<string, string> GetBodyParameters()
285317
return dict;
286318
}
287319

320+
/// <summary>
321+
/// Gets the CCS header for the client credentials flow
322+
/// </summary>
323+
/// <param name="additionalBodyParameters"></param>
324+
/// <returns></returns>
288325
protected override KeyValuePair<string, string>? GetCcsHeader(IDictionary<string, string> additionalBodyParameters)
289326
{
290327
return null;

tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,8 @@ public void ConfidentialClient_WithInvalidAuthority_ThrowsArgumentException()
21572157
[TestMethod]
21582158
public async Task WithAccessTokenSha256ToRefresh_MatchingHash_GetsTokenFromIdp_Async()
21592159
{
2160+
const string accessToken = "access-token";
2161+
21602162
// Arrange
21612163
using (var httpManager = new MockHttpManager())
21622164
{
@@ -2170,19 +2172,19 @@ public async Task WithAccessTokenSha256ToRefresh_MatchingHash_GetsTokenFromIdp_A
21702172
.BuildConcrete();
21712173

21722174
// 1) First network call: populates the cache with "access-token"
2173-
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: "access-token");
2175+
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: accessToken);
21742176
AuthenticationResult initialResult = await app.AcquireTokenForClient(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false);
21752177

2176-
Assert.AreEqual("access-token", initialResult.AccessToken);
2178+
Assert.AreEqual(accessToken, initialResult.AccessToken);
21772179
Assert.AreEqual(TokenSource.IdentityProvider, initialResult.AuthenticationResultMetadata.TokenSource);
21782180

21792181
// 2) Second call: re-check the cache. Should see the same token from cache
21802182
AuthenticationResult secondResult = await app.AcquireTokenForClient(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false);
2181-
Assert.AreEqual("access-token", secondResult.AccessToken);
2183+
Assert.AreEqual(accessToken, secondResult.AccessToken);
21822184
Assert.AreEqual(TokenSource.Cache, secondResult.AuthenticationResultMetadata.TokenSource);
21832185

21842186
// 3) Now specify the same token's hash as "bad" => expect a new token from IdP
2185-
string tokenHash = ComputeSHA256("access-token");
2187+
string tokenHash = ComputeSHA256(accessToken);
21862188

21872189
// Add another network response to simulate fetching a new token
21882190
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: "new-access-token");
@@ -2263,6 +2265,9 @@ public async Task ForceRefreshAndAccessTokenHash_ThrowsException_Async()
22632265
[TestMethod]
22642266
public async Task AcquireTokenForClient_WithClaims_And_MatchingHash_SkipsCache_Async()
22652267
{
2268+
const string oldToken = "old-token";
2269+
const string freshToken = "fresh-token";
2270+
22662271
using (var httpManager = new MockHttpManager())
22672272
{
22682273
httpManager.AddInstanceDiscoveryMockHandler();
@@ -2275,16 +2280,16 @@ public async Task AcquireTokenForClient_WithClaims_And_MatchingHash_SkipsCache_A
22752280
.WithExperimentalFeatures(true)
22762281
.BuildConcrete();
22772282

2278-
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: "old-token");
2283+
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: oldToken);
22792284
AuthenticationResult firstResult = await app.AcquireTokenForClient(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false);
22802285

2281-
Assert.AreEqual("old-token", firstResult.AccessToken);
2286+
Assert.AreEqual(oldToken, firstResult.AccessToken);
22822287

22832288
// 2) We do matching hash => a new token is returned
2284-
string tokenHash = ComputeSHA256("old-token");
2289+
string tokenHash = ComputeSHA256(oldToken);
22852290

22862291
// Add second network response for the new token
2287-
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: "fresh-token");
2292+
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: freshToken);
22882293

22892294
// Act
22902295
AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope)
@@ -2294,14 +2299,16 @@ public async Task AcquireTokenForClient_WithClaims_And_MatchingHash_SkipsCache_A
22942299
.ConfigureAwait(false);
22952300

22962301
// Assert => new token from the IDP
2297-
Assert.AreEqual("fresh-token", result.AccessToken);
2302+
Assert.AreEqual(freshToken, result.AccessToken);
22982303
Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
22992304
}
23002305
}
23012306

23022307
[TestMethod]
23032308
public async Task AcquireTokenForClient_WithClaims_And_MismatchedHash_UsesCache_Async()
23042309
{
2310+
const string cacheToken = "cache-token";
2311+
23052312
using (var httpManager = new MockHttpManager())
23062313
{
23072314
httpManager.AddInstanceDiscoveryMockHandler();
@@ -2315,13 +2322,13 @@ public async Task AcquireTokenForClient_WithClaims_And_MismatchedHash_UsesCache_
23152322
.BuildConcrete();
23162323

23172324
// First network call: populates the cache with "cache-token"
2318-
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: "cache-token");
2325+
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: cacheToken);
23192326

23202327
var initialResult = await app.AcquireTokenForClient(TestConstants.s_scope)
23212328
.ExecuteAsync()
23222329
.ConfigureAwait(false);
23232330

2324-
Assert.AreEqual("cache-token", initialResult.AccessToken);
2331+
Assert.AreEqual(cacheToken, initialResult.AccessToken);
23252332
Assert.AreEqual(TokenSource.IdentityProvider, initialResult.AuthenticationResultMetadata.TokenSource);
23262333

23272334
// 2) We'll do a mismatched hash => expect to keep using the cached token
@@ -2335,7 +2342,7 @@ public async Task AcquireTokenForClient_WithClaims_And_MismatchedHash_UsesCache_
23352342
.ConfigureAwait(false);
23362343

23372344
// Assert => we keep using the cached token
2338-
Assert.AreEqual("cache-token", result.AccessToken,
2345+
Assert.AreEqual(cacheToken, result.AccessToken,
23392346
"We reuse the cache if the hash does not match the 'bad' token’s hash.");
23402347
Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource);
23412348
}

0 commit comments

Comments
 (0)