Correlation failed, cookies not found using OpenID in ASP.net core MVC 6

cebuhax0r 26 Reputation points
2023-03-19T12:09:20.3466667+00:00

I am getting the below error in my ASP.net core MVC 6 application, my application is using Keycloak and is running in a docker container.
We connect to Keycloak using OpenID, but after logging in Keycloak this error occur

warn: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[15]3/19/2023 8:01:24 PM       '.AspNetCore.Correlation.f3GcSJfC_y2A4PpE3sdfsuCCnSonAFEyKlnWd3zo8Rg' cookie not found.3/19/2023 8:01:24 PM fail: Microsoft.AspNetCore.Server.Kestrel[13]3/19/2023 8:01:24 PM       Connection id "0HMP8E6944565", Request id "0HMP8E6944565:00000003": An unhandled exception was thrown by the application.3/19/2023 8:01:24 PM       System.Exception: An error was encountered while handling the remote login.3/19/2023 8:01:24 PM        ---> System.Exception: Correlation failed.3/19/2023 8:01:24 PM          --- End of inner exception stack trace ---3/19/2023 8:01:24 PM          at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()3/19/2023 8:01:24 PM          at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)3/19/2023 8:01:24 PM          at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)3/19/2023 8:01:24 PM          at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)3/19/2023 8:01:24 PM          at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

so here is my Program.cs

services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        options.DefaultAuthenticateScheme = "oidc";
        options.DefaultSignInScheme = "Cookies";
    })
    .AddCookie(options =>
    {
        // add an instance of the patched manager to the options:
        options.CookieManager = new ChunkingCookieManager();

        options.Cookie.HttpOnly = true;
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    })
    .AddOpenIdConnect(options =>
    {
        options.Authority = serverURL + "/realms/" + realm;
        options.ClientId = clientTd;
        options.ClientSecret = secret;
        options.ResponseType = OpenIdConnectResponseType.Code;
        options.ResponseMode = "query";
        options.UsePkce = false;
        options.RequireHttpsMetadata = false;
        options.NonceCookie.SameSite = SameSiteMode.Lax;
        options.CorrelationCookie.SameSite = SameSiteMode.Lax;

        options.Events.OnAuthorizationCodeReceived = authorizationCtx =>
        {
            // access code thru authorizationCtx.TokenEndpointRequest.Code
            return Task.FromResult(0);
        };
        options.Events.OnTokenResponseReceived = ctx => {
            KeycloackAdapter.HandleToken(
                ctx.TokenEndpointResponse.AccessToken,
                ctx.TokenEndpointResponse.RefreshToken, 
                ctx.TokenEndpointResponse.IdToken, 
                ctx.HttpContext
            );

            return Task.FromResult(0);
        };

        options.Events.OnUserInformationReceived = userInfo =>
        {
            return Task.FromResult(0);
        };
    });


services.AddAuthorization(options =>
{
    options.AddPolicy("Keycloak", policy =>
        policy.Requirements.Add(new KeycloakPolicyRequirement()));
});

services.AddTransient<IAuthorizationHandler, KeycloakPolicyHandler>();

services.AddMvc().AddNewtonsoftJson(o =>
{
    // prevent JSON from changing to camelCase
    o.UseMemberCasing();
});

services.AddDataProtection().PersistKeysToFileSystem(
    new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));

services.AddDataProtection().UseCryptographicAlgorithms(
    new AuthenticatedEncryptorConfiguration
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });

services.AddRazorPages().AddSessionStateTempDataProvider();
services.AddControllersWithViews().AddSessionStateTempDataProvider();

services.AddSession(options => {
    options.IdleTimeout = TimeSpan.FromHours(12);
    options.Cookie.IsEssential = true;
});

services.AddHttpContextAccessor();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseHangfireDashboard();

app.UseCookiePolicy(new CookiePolicyOptions()
{
    MinimumSameSitePolicy = SameSiteMode.None,
    Secure = CookieSecurePolicy.Always,
});

app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true
});

app.UseSession();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

The volume is already mounted so that data protection persist to the file system.

I have tried every single solution I can found online to no luck
What else do I need to check and do and what am I doing wrong?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,158 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,253 questions
{count} vote

2 answers

Sort by: Most helpful
  1. Sergey Tkachenko 10 Reputation points
    2023-06-16T15:54:36.2733333+00:00

    Try to add this. Maybe it will help.

    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
    	ForwardedHeaders = ForwardedHeaders.XForwardedProto
    });
    
    2 people found this answer helpful.
    0 comments No comments

  2. Yahya SÖNMEZ 5 Reputation points
    2023-03-28T06:46:46.85+00:00

    Hi,

    I have the same question for Azure App Service.

    Application Event Logs details

    Step 1 - Warning message

    Category: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler
    EventId: 15
    SpanId: 40458e41b58890ac
    TraceId: 49e341e43314292f1170a277ea012000
    ParentId: 0000000000000000
    RequestId: 8000df74-0002-ae00-b63f-84710c7967bb
    RequestPath: /signin-microsoft
    
    '.AspNetCore.Correlation.2aOWLHUdS90PTeLmdoeFmXAkDiWo4A84F504OPA-G8A' cookie not found.
    

    Step 2 - Error message

    Category: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware
    EventId: 1
    SpanId: 40458e41b58890ac
    TraceId: 49e341e43314292f1170a277ea012000
    ParentId: 0000000000000000
    RequestId: 8000df74-0002-ae00-b63f-84710c7967bb
    RequestPath: /signin-microsoft
    
    An unhandled exception has occurred while executing the request.
    
    Exception: 
    System.Exception: An error was encountered while handling the remote login.
     ---> System.Exception: Correlation failed.
       --- End of inner exception stack trace ---
       at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    

    3- Program.cs code

    builder.Services.AddOpenIddict()
    
                // Register the OpenIddict core components.
                .AddCore(options =>
                {
                    // Configure OpenIddict to use the Entity Framework Core stores and models.
                    // Note: call ReplaceDefaultEntities() to replace the default OpenIddict entities.
                    options.UseEntityFrameworkCore()
                           .UseDbContext<ApplicationDbContext>();
    
                    // Enable Quartz.NET integration.
                    options.UseQuartz();
                })
    
                // Register the OpenIddict server components.
                .AddServer(options =>
                {
                    options.SetAccessTokenLifetime(TimeSpan.FromDays(1));
                    options.SetRefreshTokenLifetime(TimeSpan.FromDays(1));
                    // Enable the authorization, logout, token and userinfo endpoints.
                    options.SetAuthorizationEndpointUris("/connect/authorize")
                            .SetLogoutEndpointUris("/connect/logout")
                            .SetIntrospectionEndpointUris("/connect/introspect")
                            .SetTokenEndpointUris("/connect/token")
                            .SetUserinfoEndpointUris("/connect/userinfo")
                            .SetVerificationEndpointUris("/connect/verify");
                    // Mark the "email", "profile" and "roles" scopes as supported scopes.
                    options.RegisterScopes(Scopes.Email, Scopes.Profile, Scopes.Roles, Scopes.Phone, Scopes.OfflineAccess, Scopes.OfflineAccess);
    
                    // Note: this sample only uses the authorization code flow but you can enable
                    // the other flows if you need to support implicit, password or client credentials.
                    options.AllowAuthorizationCodeFlow().AllowRefreshTokenFlow();
                    // Enable the password flow.
                    options.AllowPasswordFlow().AllowRefreshTokenFlow();
                    // Enable the client credentials flow.
                    options.AllowClientCredentialsFlow().AllowRefreshTokenFlow();
    
                    options.AllowHybridFlow().AllowRefreshTokenFlow();
    
                    // Register the signing and encryption credentials.
                    options.AddDevelopmentEncryptionCertificate()
                       .AddDevelopmentSigningCertificate();
    
                    options.DisableAccessTokenEncryption();
                    options.UseAspNetCore()
                       .EnableAuthorizationEndpointPassthrough()
                       .EnableLogoutEndpointPassthrough()
                       .EnableTokenEndpointPassthrough()
                       .EnableUserinfoEndpointPassthrough()
                       .EnableStatusCodePagesIntegration();
    
                })
    
                // Register the OpenIddict validation components.
                .AddValidation(options =>
                {
                    // Import the configuration from the local OpenIddict server instance.
                    options.UseLocalServer();
    
                    // Register the ASP.NET Core host.
                    options.UseAspNetCore();
                });
    
    builder.Services.AddAuthentication()
         .AddOpenIdConnect(
            builder.Configuration["Authentication:Microsoft:Name"],
            builder.Configuration["Authentication:Microsoft:DisplayName"],
            options =>
         {
             options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
             options.ClientId = builder.Configuration["Authentication:Microsoft:ClientId"];
             options.ClientSecret = builder.Configuration["Authentication:Microsoft:ClientSecret"];
             options.Authority = builder.Configuration["Authentication:Microsoft:Authority"];
             options.SignInScheme = "Identity.External";
             options.RemoteAuthenticationTimeout = TimeSpan.FromSeconds(30);
             options.ResponseType = "code";
             options.UsePkce = false; // live does not support this yet
             options.CallbackPath = "/signin-microsoft";
             options.Prompt = "login"; // login, consent
             options.Scope.Add("openid");
             options.Scope.Add("profile");
             options.Scope.Add(builder.Configuration["Authentication:Microsoft:ScopeApi"]);
             options.SaveTokens = true;
             options.NonceCookie.SameSite = SameSiteMode.None;
             options.CorrelationCookie.SameSite = SameSiteMode.None;
             options.TokenValidationParameters = new TokenValidationParameters
             {
                 ValidateIssuer = false,
                 NameClaimType = "email",
             };
         });
    
    builder.Services.Configure<CookiePolicyOptions>(options =>
    {
        options.MinimumSameSitePolicy = SameSiteMode.None;
        options.Secure = CookieSecurePolicy.Always;
    });
    ...
    var app = builder.Build();
    app.UseCookiePolicy();
    ...
    
    1 person found this answer helpful.
    0 comments No comments