Skip to content

Commit 935ea1e

Browse files
Update MSIv1 Token Revocation's token_sha256_to_refresh param to use sha256's HEX representation (#5229)
* hex * test method fix * pr comments * pr comments --------- Co-authored-by: Gladwin Johnson <[email protected]>
1 parent 8c37304 commit 935ea1e

File tree

4 files changed

+24
-19
lines changed

4 files changed

+24
-19
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ private bool ShouldUseCachedToken(MsalAccessTokenCacheItem cacheItem)
256256
/// <returns></returns>
257257
private bool IsMatchingTokenHash(string tokenSecret, string accessTokenHashToRefresh)
258258
{
259-
string cachedTokenHash = _cryptoManager.CreateSha256Hash(tokenSecret);
259+
string cachedTokenHash = _cryptoManager.CreateSha256HashHex(tokenSecret);
260260
return string.Equals(cachedTokenHash, accessTokenHashToRefresh, StringComparison.Ordinal);
261261
}
262262

src/client/Microsoft.Identity.Client/PlatformsCommon/Interfaces/ICryptographyManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ internal interface ICryptographyManager
1111
string CreateBase64UrlEncodedSha256Hash(string input);
1212
string GenerateCodeVerifier();
1313
string CreateSha256Hash(string input);
14+
string CreateSha256HashHex(string input);
1415
byte[] CreateSha256HashBytes(string input);
1516
byte[] SignWithCertificate(string message, X509Certificate2 certificate, RSASignaturePadding signaturePadding);
1617
}

src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/CommonCryptographyManager.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ public byte[] CreateSha256HashBytes(string input)
5656
}
5757
}
5858

59+
public string CreateSha256HashHex(string input)
60+
{
61+
if (string.IsNullOrEmpty(input))
62+
{
63+
return null;
64+
}
65+
66+
byte[] hashBytes = CreateSha256HashBytes(input);
67+
68+
// Convert to hex using BitConverter, removing dashes and forcing lowercase
69+
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
70+
}
71+
5972
/// <remarks>AAD only supports RSA certs for client credentials </remarks>
6073
public virtual byte[] SignWithCertificate(string message, X509Certificate2 certificate, RSASignaturePadding signaturePadding)
6174
{

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

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,7 +2164,8 @@ public void ConfidentialClient_WithInvalidAuthority_ThrowsArgumentException()
21642164
[TestMethod]
21652165
public async Task WithAccessTokenSha256ToRefresh_MatchingHash_GetsTokenFromIdp_Async()
21662166
{
2167-
const string accessToken = "access-token";
2167+
const string accessToken = "test_token";
2168+
const string accessTokenHash = "cc0af97287543b65da2c7e1476426021826cab166f1e063ed012b855ff819656";
21682169

21692170
// Arrange
21702171
using (var httpManager = new MockHttpManager())
@@ -2190,14 +2191,12 @@ public async Task WithAccessTokenSha256ToRefresh_MatchingHash_GetsTokenFromIdp_A
21902191
Assert.AreEqual(TokenSource.Cache, secondResult.AuthenticationResultMetadata.TokenSource);
21912192

21922193
// 3) Now specify the same token's hash as "bad" => expect a new token from IdP
2193-
string tokenHash = ComputeSHA256(accessToken);
2194-
21952194
// Add another network response to simulate fetching a new token
21962195
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: "new-access-token");
21972196

21982197
// Act: Use matching hash => triggers new token request
21992198
AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope)
2200-
.WithAccessTokenSha256ToRefresh(tokenHash)
2199+
.WithAccessTokenSha256ToRefresh(accessTokenHash)
22012200
.ExecuteAsync()
22022201
.ConfigureAwait(false);
22032202

@@ -2231,7 +2230,7 @@ public async Task WithAccessTokenSha256ToRefresh_MismatchedHash_UsesCache_Async(
22312230

22322231
// 2) Mismatched hash => we expect to keep using the cached token
22332232
// Act
2234-
var mismatchHash = ComputeSHA256("some-other-token");
2233+
var mismatchHash = ComputeSHA256Hex("some-other-token");
22352234
AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope)
22362235
.WithAccessTokenSha256ToRefresh(mismatchHash)
22372236
.ExecuteAsync()
@@ -2289,7 +2288,7 @@ public async Task AcquireTokenForClient_WithClaims_And_MatchingHash_SkipsCache_A
22892288
Assert.AreEqual(oldToken, firstResult.AccessToken);
22902289

22912290
// 2) We do matching hash => a new token is returned
2292-
string tokenHash = ComputeSHA256(oldToken);
2291+
string tokenHash = ComputeSHA256Hex(oldToken);
22932292

22942293
// Add second network response for the new token
22952294
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(token: freshToken);
@@ -2334,7 +2333,7 @@ public async Task AcquireTokenForClient_WithClaims_And_MismatchedHash_UsesCache_
23342333
Assert.AreEqual(TokenSource.IdentityProvider, initialResult.AuthenticationResultMetadata.TokenSource);
23352334

23362335
// 2) We'll do a mismatched hash => expect to keep using the cached token
2337-
string mismatchedHash = ComputeSHA256("some-other-token");
2336+
string mismatchedHash = ComputeSHA256Hex("some-other-token");
23382337

23392338
// Act
23402339
var result = await app.AcquireTokenForClient(TestConstants.s_scope)
@@ -2350,18 +2349,10 @@ public async Task AcquireTokenForClient_WithClaims_And_MismatchedHash_UsesCache_
23502349
}
23512350
}
23522351

2353-
private static string ComputeSHA256(string token)
2352+
private static string ComputeSHA256Hex(string token)
23542353
{
2355-
#if NET6_0_OR_GREATER
2356-
byte[] hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(token));
2357-
return Convert.ToBase64String(hashBytes);
2358-
#else
2359-
using (var sha256 = SHA256.Create())
2360-
{
2361-
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(token));
2362-
return Convert.ToBase64String(hashBytes);
2363-
}
2364-
#endif
2354+
var cryptoMgr = new CommonCryptographyManager();
2355+
return cryptoMgr.CreateSha256HashHex(token);
23652356
}
23662357
}
23672358
}

0 commit comments

Comments
 (0)