.NET 7 Authentication setup goes in infinite loop

102 Views Asked by At

This is an intermittent issue that has only happened in one instance so far in an Azure Web Application. The process crashed with a stack overflow error when trying to register the Authentication service in Startup.cs. Here is the stack overflow error:

========================================================
 Dump Analysis for w3wp__prod-appservice-eus__b6c9__PID__5408__Date__05_04_2023__Time_06_29_42AM__935__ntdll!ZwTerminateProcess_pd0mdwk0007S7.dmp
========================================================
Thread 424
ExitCode 800703E9
ExitCodeString COR_E_STACKOVERFLOW
DefaultHostName prod-appservice-eus.azurewebsites.net
Managed Exception = System.StackOverflowException:
CallStack - Managed Exception
========================================================
CallStack - Crashing Thread
========================================================
     FaultingExceptionFrame
     InlinedCallFrame
     System.Globalization.CompareInfo.FindString(UInt32, System.ReadOnlySpan`1<Char>, System.ReadOnlySpan`1<Char>, Int32*)
     System.Globalization.CompareInfo.IsPrefix(System.ReadOnlySpan`1<Char>, System.ReadOnlySpan`1<Char>, System.Globalization.CompareOptions)
     System.String.StartsWith(System.String, System.StringComparison)
     AppService.StartupExtensions.Services.AuthenticationAndHttpClientsSetup+<>c.<RegisterAuthenticationServices>b__2_4(Microsoft.AspNetCore.Http.HttpContext)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1[[System.__Canon, System.Private.CoreLib]].ResolveTarget(System.String)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]].MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1[[System.__Canon, System.Private.CoreLib]].ForbidAsync(Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16.MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16, Microsoft.AspNetCore.Authentication.Core]](<ForbidAsync>d__16 ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16, Microsoft.AspNetCore.Authentication.Core]](<ForbidAsync>d__16 ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(Microsoft.AspNetCore.Http.HttpContext, System.String, Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]].MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1[[System.__Canon, System.Private.CoreLib]].ForbidAsync(Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16.MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16, Microsoft.AspNetCore.Authentication.Core]](<ForbidAsync>d__16 ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16, Microsoft.AspNetCore.Authentication.Core]](<ForbidAsync>d__16 ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(Microsoft.AspNetCore.Http.HttpContext, System.String, Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]].MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1[[System.__Canon, System.Private.CoreLib]].ForbidAsync(Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16.MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16, Microsoft.AspNetCore.Authentication.Core]](<ForbidAsync>d__16 ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16, Microsoft.AspNetCore.Authentication.Core]](<ForbidAsync>d__16 ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(Microsoft.AspNetCore.Http.HttpContext, System.String, Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]].MoveNext()
     System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<ForbidAsync>d__55[[System.__Canon, System.Private.CoreLib]], Microsoft.AspNetCore.Authentication]](<ForbidAsync>d__55<System.__Canon> ByRef)
     Microsoft.AspNetCore.Authentication.AuthenticationHandler`1[[System.__Canon, System.Private.CoreLib]].ForbidAsync(Microsoft.AspNetCore.Authentication.AuthenticationProperties)
     Microsoft.AspNetCore.Authentication.AuthenticationService+<ForbidAsync>d__16.MoveNext()

As you can see, the Microsoft libraries for Authentication seems to get caught in an endless loop which eventually results in a "recursion too deep" stack overflow.

Here is the code I used to setup authentication:

            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultChallengeScheme = "DerivedScheme";
                sharedOptions.DefaultAuthenticateScheme = "DerivedScheme";
            })
                .AddPolicyScheme("DerivedScheme", "Authorization Bearer or Token", options =>
                {
                    options.ForwardDefaultSelector = context =>
                    {
                        var scheme = context?.Request?.Headers["Authorization"].FirstOrDefault()?.StartsWith("Bearer ") == true
                            ? JwtBearerDefaults.AuthenticationScheme
                            : WsFederationDefaults.AuthenticationScheme;
                        return scheme;
                    };
                })
                .AddJwtBearer(options =>
                {
                    options.Authority = configuration["Auth:OIDC:Authority"];
                    options.Audience = configuration["Auth:OIDC:ApiName"];
                    options.SaveToken = true;
                    options.MapInboundClaims = false;
                    options.TokenValidationParameters.ValidIssuers = configuration["Auth:OIDC:ValidIssuers"].Split(',').ToList();
                })
                .AddBentleyImsWsFederationAuthentication(WsFederationDefaults.AuthenticationScheme, o =>
                {
                    configuration.GetSection("Auth").GetSection("WsFed").Bind(o);
                    List<string> audienceUriList = configuration["Auth:WsFed:TokenValidationParameters:ValidAudiencesURIs"].Split(',').ToList();
                    o.TokenValidationParameters.ValidAudiences = audienceUriList;
                    o.PassiveRedirect = false;
                    o.SkipUnrecognizedRequests = true;
                    o.BootStrapTokenClaimName = _tokenName;
                });

Any ideas as to what could cause this to fail with a stack overflow error intermittently?

0

There are 0 best solutions below