microsoft-identity-web: [Bug] Adding Redis as Distributed Cache Triggers NullReferenceException
Which Version of Microsoft Identity Web are you using ? 0.1.1 preview
Where is the issue?
- Web App
- Sign-in users
- Sign-in users and call web APIs
- Web API
- Protected web APIs (Validating tokens)
- Protected web APIs (Validating scopes)
- Protected web APIs call downstream web APIs
- Token cache serialization
- In Memory caches
- Session caches
- Distributed caches
Other? - please describe;
Is this a new or existing app? Transitioning and existing application from the V1 endpoints to V2 and using this library. The conversion is just about complete but cannot finish testing with this bug in place.
Repro Simply adding Redis distributed cache to the tail of the services collection causes a NullReferenceException when attempting to fetch access token. Apparently, for some reason, this causes the HttpContextAccessor to return a null.
public static IServiceCollection AddDistributedOrLocalMemoryCache(this IServiceCollection services, IConfiguration configuration) {
services.AddDistributedTokenCaches();
services.AddDistributedRedisCache((RedisCacheOptions redisOptions) => {
redisOptions.Configuration = configuration.RedisConnectionString();
redisOptions.InstanceName = $"fischer-web-app-{configuration.EnvironmentName().ToLower()}: ";
});
return services;
}
Expected behavior No exception
Actual behavior A NullReferenceException is thrown
Possible Solution Still investigating
Additional context/ Logs / Screenshots
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.Identity.Web
StackTrace:
at Microsoft.Identity.Web.HttpContextExtensions.GetTokenUsedToCallWebAPI(HttpContext httpContext) in D:\a\1\s\src\Microsoft.Identity.Web\HttpContextExtensions.cs:line 29
at Microsoft.Identity.Web.TokenCacheProviders.MsalAbstractTokenCacheProvider.GetCacheKey(Boolean isAppTokenCache) in D:\a\1\s\src\Microsoft.Identity.Web\TokenCacheProviders\MsalAbstractTokenCacheProvider.cs:line 66
at Microsoft.Identity.Web.TokenCacheProviders.MsalAbstractTokenCacheProvider.<OnBeforeAccessAsync>d__6.MoveNext() in D:\a\1\s\src\Microsoft.Identity.Web\TokenCacheProviders\MsalAbstractTokenCacheProvider.cs:line 94
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 474
at Microsoft.Identity.Client.TokenCache.<Microsoft-Identity-Client-ITokenCacheInternal-OnBeforeAccessAsync>d__104.MoveNext() in D:\a\1\s\src\client\Microsoft.Identity.Client\TokenCache.Notifications.cs:line 47
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 474
at Microsoft.Identity.Client.Cache.CacheSessionManager.<RefreshCacheForReadOperationsAsync>d__13.MoveNext() in D:\a\1\s\src\client\Microsoft.Identity.Client\Cache\CacheSessionManager.cs:line 115
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 474
at Microsoft.Identity.Client.Cache.CacheSessionManager.<GetAccountsAsync>d__12.MoveNext() in D:\a\1\s\src\client\Microsoft.Identity.Client\Cache\CacheSessionManager.cs:line 83
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 563 at Microsoft.Identity.Client.ClientApplicationBase.<GetAccountsAsync>d__14.MoveNext() in D:\a\1\s\src\client\Microsoft.Identity.Client\ClientApplicationBase.cs:line 113 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in /_/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable
1.ConfiguredTaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 563
at Microsoft.Identity.Web.TokenAcquisition.<GetAccessTokenOnBehalfOfUserFromCacheAsync>d__17.MoveNext() in D:\a\1\s\src\Microsoft.Identity.Web\TokenAcquisition.cs:line 410
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 563 at Microsoft.Identity.Web.TokenAcquisition.<GetAccessTokenForUserAsync>d__12.MoveNext() in D:\a\1\s\src\Microsoft.Identity.Web\TokenAcquisition.cs:line 203 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in /_/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in /_/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151 at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 369
at WebApp.Startup.<TryRelay>d__6.MoveNext() in G:\acquisitions.visualstudio.com\acquisition-web-app-2\src\Startup.cs:line 98
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 180
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 151
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() in //src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs:line 107
at WebApp.Startup.<>c__DisplayClass5_0.<<Configure>b__0>d.MoveNext() in G:\acquisitions.visualstudio.com\acquisition-web-app-2\src\Startup.cs:line 66
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in //src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs:line 63
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_1(Object state) in //src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs:line 1954
at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi) in //src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs:line 808
at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callback, TState& state) in //src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs:line 335
at System.Threading.QueueUserWorkItemCallback.Execute() in //src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs:line 824
at System.Threading.ThreadPoolWorkQueue.Dispatch() in //src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs:line 677
at System.Threading.ThreadPoolWaitCallback.PerformWaitCallback() in //src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs:line 29
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 32 (12 by maintainers)
@strisys : proposing to close this issue since this is working for you now. Feel free to reopen.
So far so good as I have not seen the issue since the race condition was corrected.
I was able to find the race condition in my middleware and will see if I can reproduce the
NullReferenceException
going forward. So far so goodThose too … code that is context sensitive (in your case HttpContext) should not use
ConfigureAwait(false)