Skip to content

Commit bff5d76

Browse files
trwalketrwalkebgavrilMSgladjohn
authored
Enable IAuthenticationOperation2 to reject MSAL cached tokens and fetch new ones from ESTS (#5567)
* Initial prototype * Initial prototype * Refactoring * Reverting csproj changes * Apply suggestions from code review Co-authored-by: Gladwin Johnson <90415114+gladjohn@users.noreply.github.com> --------- Co-authored-by: trwalke <trwalke@microsoft.com> Co-authored-by: Bogdan Gavril <bogavril@microsoft.com> Co-authored-by: Gladwin Johnson <90415114+gladjohn@users.noreply.github.com>
1 parent 41ecffb commit bff5d76

File tree

17 files changed

+274
-9
lines changed

17 files changed

+274
-9
lines changed

src/client/Microsoft.Identity.Client/AuthScheme/Bearer/BearerAuthenticationOperation.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,11 @@ public IReadOnlyDictionary<string, string> GetTokenRequestParams()
3838
// ESTS issues Bearer tokens by default, no need for any extra params
3939
return CollectionHelpers.GetEmptyDictionary<string, string>();
4040
}
41+
42+
public Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData)
43+
{
44+
// no-op
45+
return Task.FromResult(true);
46+
}
4147
}
4248
}

src/client/Microsoft.Identity.Client/AuthScheme/IAuthenticationOperation2.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,12 @@ public interface IAuthenticationOperation2 : IAuthenticationOperation
1717
/// Will be invoked instead of IAuthenticationOperation.FormatResult
1818
/// </summary>
1919
Task FormatResultAsync(AuthenticationResult authenticationResult, CancellationToken cancellationToken = default);
20+
21+
/// <summary>
22+
/// Determines whether the cached token is still valid.
23+
/// </summary>
24+
/// <param name="cachedTokenData">Data used to determine if token is still valid</param>
25+
/// <returns></returns>
26+
Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData);
2027
}
2128
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Collections.Generic;
5+
6+
namespace Microsoft.Identity.Client.AuthScheme
7+
{
8+
/// <summary>
9+
/// Data used to validate cache items for different authentication schemes.
10+
/// </summary>
11+
public class MsalCacheValidationData
12+
{
13+
/// <summary>
14+
/// Gets the persisted parameters addded to the cache items.
15+
/// </summary>
16+
public IDictionary<string, string> PersistedCacheParameters { get; internal set; }
17+
}
18+
}

src/client/Microsoft.Identity.Client/AuthScheme/PoP/MtlsPopAuthenticationOperation.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,11 @@ public void FormatResult(AuthenticationResult authenticationResult)
4848
{
4949
authenticationResult.BindingCertificate = _mtlsCert;
5050
}
51+
52+
public Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData)
53+
{
54+
// no-op
55+
return Task.FromResult(true);
56+
}
5157
}
5258
}

src/client/Microsoft.Identity.Client/AuthScheme/PoP/PopAuthenticationOperation.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,11 @@ private string CreateJWS(string payload, string header)
172172

173173
return sb.ToString();
174174
}
175+
176+
public Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData)
177+
{
178+
// no-op
179+
return Task.FromResult(true);
180+
}
175181
}
176182
}

src/client/Microsoft.Identity.Client/AuthScheme/PoP/PopBrokerAuthenticationOperation.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,11 @@ public IReadOnlyDictionary<string, string> GetTokenRequestParams()
4040
{
4141
return CollectionHelpers.GetEmptyDictionary<string, string>();
4242
}
43+
44+
public Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData)
45+
{
46+
// no-op
47+
return Task.FromResult(true);
48+
}
4349
}
4450
}

src/client/Microsoft.Identity.Client/AuthScheme/SSHCertificates/SSHCertAuthenticationOperation.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,11 @@ public IReadOnlyDictionary<string, string> GetTokenRequestParams()
6060
{ OAuth2Parameter.RequestConfirmation , _jwk }
6161
};
6262
}
63+
64+
public Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData)
65+
{
66+
// no-op
67+
return Task.FromResult(true);
68+
}
6369
}
6470
}

src/client/Microsoft.Identity.Client/Extensibility/ExternalBoundTokenScheme.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,11 @@ public IReadOnlyDictionary<string, string> GetTokenRequestParams()
4444
{
4545
return CollectionHelpers.GetEmptyDictionary<string, string>();
4646
}
47+
48+
public Task<bool> ValidateCachedTokenAsync(MsalCacheValidationData cachedTokenData)
49+
{
50+
// no-op
51+
return Task.FromResult(true);
52+
}
4753
}
4854
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Threading;
1111
using System.Threading.Tasks;
1212
using Microsoft.Identity.Client.ApiConfig.Parameters;
13+
using Microsoft.Identity.Client.AuthScheme;
1314
using Microsoft.Identity.Client.Cache.Items;
1415
using Microsoft.Identity.Client.Core;
1516
using Microsoft.Identity.Client.Extensibility;
@@ -76,6 +77,21 @@ protected override async Task<AuthenticationResult> ExecuteAsync(CancellationTok
7677

7778
MsalAccessTokenCacheItem cachedAccessTokenItem = await GetCachedAccessTokenAsync().ConfigureAwait(false);
7879

80+
// Validate the cached token using the authentication operation
81+
if (AuthenticationRequestParameters.AuthenticationScheme != null &&
82+
cachedAccessTokenItem != null &&
83+
AuthenticationRequestParameters.AuthenticationScheme is IAuthenticationOperation2 authOp2)
84+
{
85+
var cacheValidationData = new MsalCacheValidationData();
86+
cacheValidationData.PersistedCacheParameters = cachedAccessTokenItem.PersistedCacheParameters;
87+
88+
if (!await authOp2.ValidateCachedTokenAsync(cacheValidationData).ConfigureAwait(false))
89+
{
90+
logger.Info("[ClientCredentialRequest] Cached token failed authentication operation validation.");
91+
cachedAccessTokenItem = null;
92+
}
93+
}
94+
7995
// No access token or cached access token needs to be refreshed
8096
if (cachedAccessTokenItem != null)
8197
{

src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<Compile Include="$(PathToMsalSources)\Platforms\Features\DesktopOS\**\*.cs" />
9393
<Compile Include="$(PathToMsalSources)\Platforms\Features\DefaultOSBrowser\**\*.cs" />
9494
<Compile Include="$(PathToMsalSources)\Platforms\Features\OpenTelemetry\**\*.cs" />
95-
95+
9696
<PackageReference Include="System.Diagnostics.DiagnosticSource" />
9797
<PackageReference Include="System.Formats.Asn1" />
9898
<PackageReference Include="System.Security.Cryptography.Cng" />
@@ -104,7 +104,7 @@
104104
<Compile Include="$(PathToMsalSources)\Platforms\Features\DefaultOSBrowser\**\*.cs" />
105105
<Compile Include="$(PathToMsalSources)\Platforms\Features\DesktopOS\**\*.cs" />
106106
<Compile Include="$(PathToMsalSources)\Platforms\Features\OpenTelemetry\**\*.cs" />
107-
107+
108108
<!--System.Text.Json replaces internal NewtonSoft for NET -->
109109
<Compile Remove="$(PathToMsalSources)\json\**\*.*" />
110110

@@ -161,4 +161,4 @@
161161
<AdditionalFiles Include="PublicAPI/$(TargetFramework)/PublicAPI.Unshipped.txt" />
162162
</ItemGroup>
163163

164-
</Project>
164+
</Project>

0 commit comments

Comments
 (0)