Skip to content

Commit 3fb8503

Browse files
committed
Use MemoryCache instead of static cache in MSAL
1 parent 101c3c7 commit 3fb8503

3 files changed

Lines changed: 78 additions & 15 deletions

File tree

src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -944,11 +944,6 @@ private async Task<IConfidentialClientApplication> BuildConfidentialClientApplic
944944
enablePiiLogging: mergedOptions.ConfidentialClientApplicationOptions.EnablePiiLogging)
945945
.WithExperimentalFeatures();
946946

947-
if (_tokenCacheProvider is MsalMemoryTokenCacheProvider)
948-
{
949-
builder.WithCacheOptions(CacheOptions.EnableSharedCacheOptions);
950-
}
951-
952947
string? currentUri = _tokenAcquisitionHost.GetCurrentRedirectUri(mergedOptions);
953948

954949
// The redirect URI is not needed for OBO
@@ -1004,11 +999,8 @@ await builder.WithClientCredentialsAsync(
1004999
NotifyCertificateSelection(mergedOptions, app, CerticateObserverAction.Selected, null);
10051000

10061001
// Initialize token cache providers
1007-
if (!(_tokenCacheProvider is MsalMemoryTokenCacheProvider))
1008-
{
1009-
_tokenCacheProvider.Initialize(app.AppTokenCache);
1010-
_tokenCacheProvider.Initialize(app.UserTokenCache);
1011-
}
1002+
_tokenCacheProvider.Initialize(app.AppTokenCache);
1003+
_tokenCacheProvider.Initialize(app.UserTokenCache);
10121004

10131005
return app;
10141006
}
@@ -1452,7 +1444,7 @@ private void Log(
14521444
/// Temporary. Replace with Builder.WithClientAssertion when MSAL.NET supports it.
14531445
/// </summary>
14541446
private static bool OverrideClientAssertionIfNeeded<T>(TokenAcquisitionOptions? tokenAcquisitionOptions, AbstractConfidentialClientAcquireTokenParameterBuilder<T> builder)
1455-
where T: AbstractAcquireTokenParameterBuilder<T>
1447+
where T : AbstractAcquireTokenParameterBuilder<T>
14561448
{
14571449
if (tokenAcquisitionOptions == null || tokenAcquisitionOptions.ExtraParameters == null)
14581450
{

tests/Microsoft.Identity.Web.Test/TokenAcquisitionAuthorityTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public async Task VerifyCorrectAuthorityUsedInTokenAcquisition_B2CAuthorityTests
140140

141141
Assert.Equal(expectedAuthority, app.Authority);
142142
}
143-
143+
144144
[Theory]
145145
[InlineData("https://localhost:1234")]
146146
[InlineData("")]
@@ -478,9 +478,9 @@ public async Task GetOrBuildManagedIdentity_TestAsync(string? clientId)
478478
InitializeTokenAcquisitionObjects();
479479

480480
// Act
481-
var app1 =
481+
var app1 =
482482
await _tokenAcquisition.GetOrBuildManagedIdentityApplicationAsync(mergedOptions, managedIdentityOptions);
483-
var app2 =
483+
var app2 =
484484
await _tokenAcquisition.GetOrBuildManagedIdentityApplicationAsync(mergedOptions, managedIdentityOptions);
485485

486486
// Assert

tests/Microsoft.Identity.Web.Test/TokenAcquisitionTests.cs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66
using System.Net.Http;
77
using System.Threading;
88
using System.Threading.Tasks;
9+
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
10+
using Microsoft.Extensions.Caching.Memory;
911
using Microsoft.Extensions.DependencyInjection;
12+
using Microsoft.Extensions.Logging;
13+
using Microsoft.Extensions.Options;
1014
using Microsoft.Identity.Abstractions;
1115
using Microsoft.Identity.Client;
1216
using Microsoft.Identity.Web.Test.Common;
1317
using Microsoft.Identity.Web.Test.Common.Mocks;
18+
using Microsoft.Identity.Web.Test.Common.TestHelpers;
1419
using Microsoft.Identity.Web.TestOnly;
20+
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
1521
using Xunit;
16-
22+
using TC = Microsoft.Identity.Web.Test.Common.TestConstants;
1723

1824
namespace Microsoft.Identity.Web.Test
1925
{
@@ -126,6 +132,71 @@ public async Task ExtraBodyParametersAreSentToEndpointTest()
126132
Assert.Equal("Bearer header.payload.signature", result);
127133
}
128134

135+
// https://github.com/AzureAD/microsoft-identity-web/issues/3237
136+
[Fact]
137+
public async Task TokenAcquisitionUsesMemoryCacheWhenConfigured()
138+
{
139+
// Arrange
140+
var microsoftIdentityOptionsMonitor = new TestOptionsMonitor<MicrosoftIdentityOptions>(new MicrosoftIdentityOptions
141+
{
142+
Authority = TC.AuthorityCommonTenant,
143+
ClientId = TC.ConfidentialClientId,
144+
CallbackPath = string.Empty,
145+
});
146+
147+
var applicationOptionsMonitor = new TestOptionsMonitor<ConfidentialClientApplicationOptions>(new ConfidentialClientApplicationOptions
148+
{
149+
Instance = TC.AadInstance,
150+
RedirectUri = "https://localhost:1234",
151+
ClientSecret = TC.ClientSecret,
152+
});
153+
154+
var services = new ServiceCollection();
155+
services.AddTransient(
156+
provider => microsoftIdentityOptionsMonitor);
157+
services.AddTransient(
158+
provider => applicationOptionsMonitor);
159+
services.Configure<MergedOptions>(options => { });
160+
services.AddTokenAcquisition();
161+
services.AddLogging();
162+
services.AddAuthentication();
163+
services.AddSingleton<IMsalHttpClientFactory, MockHttpClientFactory>();
164+
services.AddMemoryCache();
165+
var provider = services.BuildServiceProvider();
166+
167+
168+
MergedOptions mergedOptions = provider.GetRequiredService<IMergedOptionsStore>().Get(OpenIdConnectDefaults.AuthenticationScheme);
169+
MergedOptions.UpdateMergedOptionsFromMicrosoftIdentityOptions(microsoftIdentityOptionsMonitor.Get(OpenIdConnectDefaults.AuthenticationScheme), mergedOptions);
170+
MergedOptions.UpdateMergedOptionsFromConfidentialClientApplicationOptions(applicationOptionsMonitor.Get(OpenIdConnectDefaults.AuthenticationScheme), mergedOptions);
171+
172+
var credentialsLoader = new DefaultCredentialsLoader();
173+
var tokenAcquisitionAspnetCoreHost = new TokenAcquisitionAspnetCoreHost(
174+
MockHttpContextAccessor.CreateMockHttpContextAccessor(),
175+
provider.GetService<IMergedOptionsStore>()!,
176+
provider);
177+
var tokenAcquisition = new TokenAcquisitionAspNetCore(
178+
new MsalTestTokenCacheProvider(
179+
provider.GetService<IMemoryCache>()!,
180+
provider.GetService<IOptions<MsalMemoryTokenCacheOptions>>()!),
181+
provider.GetService<IHttpClientFactory>()!,
182+
provider.GetService<ILogger<TokenAcquisition>>()!,
183+
tokenAcquisitionAspnetCoreHost,
184+
provider,
185+
credentialsLoader);
186+
var mockHttpClient = provider.GetRequiredService<IMsalHttpClientFactory>() as MockHttpClientFactory;
187+
188+
IConfidentialClientApplication app = await tokenAcquisition.GetOrBuildConfidentialClientApplicationAsync(mergedOptions);
189+
mockHttpClient!.AddMockHandler(MockHttpCreator.CreateClientCredentialTokenHandler());
190+
191+
// Act
192+
var result = await app.AcquireTokenForClient(new[] { "r" }).ExecuteAsync();
193+
194+
// Assert
195+
Assert.Equal(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
196+
IMemoryCache memoryCache = provider.GetService<IMemoryCache>()!;
197+
Assert.Equal(1, (memoryCache as MemoryCache)!.Count); // this proves that MemoryCache is used
198+
}
199+
129200
private TokenAcquirerFactory InitTokenAcquirerFactory()
130201
{
131202
TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest();

0 commit comments

Comments
 (0)