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.ConfiguredTaskAwaitable1.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.TaskAwaiter1.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)

Most upvoted comments

@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 good

Those too … code that is context sensitive (in your case HttpContext) should not use ConfigureAwait(false)