OrchardCMS / OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.
https://orchardcore.net
BSD 3-Clause "New" or "Revised" License
7.35k stars 2.37k forks source link

Session cache key XXXX-b2c_1a_signup_signin.XXXX not found in session {guid} #16446

Closed itharoopteja closed 3 weeks ago

itharoopteja commented 1 month ago

Describe the bug

I am using Azure AD B2C for authentication and I am using Orchard Core for multi tenant in my mvc app(.Net 8). In this application there are multiple tenants and multiple modules as well.

Orchard Core version

OrchardCore.Application.Mvc.Targets -> 1.8.2 OrchardCore.Application.Module.Targets -> 1.8.2

To Reproduce

Steps to reproduce the behavior:

  1. I am using Azure AD B2C Custom policies and OpenID authentication

  2. For authentication in mvc app I am using Microsoft.Identity.Web package and the code snippet is as follows to get the token

    tenantServices.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
    builder.Configuration.Bind("AzureAdB2C", options); 
    }
    , cookieOptions =>
    {
    cookieOptions.Cookie.Name = "." + shellConfiguration.GetValue<string>("CustomTitle") + ".Session";
    cookieOptions.ExpireTimeSpan = TimeSpan.FromSeconds(1800);
    cookieOptions.SlidingExpiration = true;
    cookieOptions.Cookie.IsEssential = true;
    }).EnableTokenAcquisitionToCallDownstreamApi(new string[] { builder.Configuration["Scope"] }).AddDistributedTokenCaches()
  3. After successful authentication. I am getting the token and also cookie is set in the website(browser). For the first few minutes the website works fine.

  4. After some time the api calls starts failing with these errors

    a.  Error unprotecting the session cookie.
        System.Security.Cryptography.CryptographicException: The key {guid} was not found in the 
        key ring. For more information go to https://aka.ms/aspnet/dataprotectionwarning

    b. Session cache key XXXX-b2c_1a_signup_signin.XXXX not found in session {guid}

  5. After I get one of the error the whole website falls off and all api calls return 500 Internal server error [how many times I hit refresh]

Expected behavior

I would expect that as long as cookie is valid the api calls should return good input.

Logs and screenshots

Error unprotecting the session cookie.
System.Security.Cryptography.CryptographicException: The key {guid} was not found in the key ring. For more information go to https://aka.ms/aspnet/dataprotectionwarning
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
   at Microsoft.AspNetCore.Session.CookieProtection.Unprotect(IDataProtector protector, String protectedText, ILogger logger)
github-actions[bot] commented 1 month ago

Thank you for submitting your first issue, awesome! 🚀 We're thrilled to receive your input. If you haven't completed the template yet, please take a moment to do so. This ensures that we fully understand your feature request or bug report. On what happens next, see the docs.

If you like Orchard Core, please star our repo and join our community channels.

Piedone commented 1 month ago

Do you use Azure Data Protection or the default one?

Are you sure no other process can remove the keyrings? If you're using the default store, they're under App_Data\Sites\<tenant name>\DataProtection-Keys.

itharoopteja commented 1 month ago

@Piedone I am using the default one.

I am able to see all the tenant folders under AppData\Sites and only one Key is getting created per tenant. But when I see logs I am getting the key not found error.

No Other process is overriding the DataProtection in the application.

I have a question

  1. Will a new key be created per login request (Login request meaning for every login from federation)?
Piedone commented 1 month ago

Hmm, strange.

No, a new key ring should only be generated when either there was no key ring yet, or the existing one expired.

While I won't be able to help from the top of my head, my hunch is that perhaps something is incompatible with OC's caching or key ring handling. My only suggestion is that you try to set up Azure B2C in a module, similar to the other Microsoft authentication features: https://github.com/OrchardCMS/OrchardCore/tree/main/src/OrchardCore.Modules/OrchardCore.Microsoft.Authentication. And if you do that, please also contribute it to OC :).

However, perhaps this isn't needed? https://github.com/OrchardCMS/OrchardCore/issues/3712

gvkries commented 1 month ago

On Discord you wrote that you are using a web farm. If that is true you need to configure some distributed data protection provider, e.g. Redis or Azure. See https://docs.orchardcore.net/en/latest/reference/modules/DataProtection.Azure/ or https://docs.orchardcore.net/en/latest/reference/modules/Redis/

Piedone commented 1 month ago

Well, that's a crucial information indeed.

itharoopteja commented 1 month ago

@gvkries @Piedone I have tried persisting data protection keys to Database, but for every tenant only one key is getting created.

Here are the changes:

 // Add a DbContext to store your Database Keys
 tenantServices.AddDbContext<MyKeyBDContext>(options =>
     options.UseSqlServer(
         builder.Configuration.GetConnectionString("MyDatabase")));

 // using Microsoft.AspNetCore.DataProtection;
 tenantServices.AddDataProtection().SetApplicationName(shellConfiguration.GetValue<string>("CustomTitle"))
     .PersistKeysToDbContext<MyKeyBDContext>().SetDefaultKeyLifetime(TimeSpan.FromDays(365));   

After running the application for multiple tenants I only see one row getting added to DB. I have even tried putting this code in individual module project but still I was getting only one row (no matter how many tenants I have opened )

For storing Data Protection keys to Azure

I have placed this code in appsettings file

"OrchardCore": {
    "OrchardCore_DataProtection_Azure": {
      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=<myaccountname>;AccountKey=<myaccountkey>;EndpointSuffix=core.windows.net",
      // Set to the Azure Blob container name. A container name must be a valid DNS name and conform to Azure container naming rules eg. lowercase only.
      "ContainerName": "dataprotection",
      "BlobName": "",
      "CreateContainer": true
    }
  }

should I make any other changes in Program.cs for this to work ? Or OC automatically triggers based on this setting in appsettings.json file ?

Piedone commented 1 month ago

I don't think we'll be able to help you if you want to store these key rings outside of OC via EF.

You only need one store; if you set up Azure Data Protection, then nothing else is needed. And yes, you only need to configure it like that.

itharoopteja commented 1 month ago

@Piedone Thanks for the clarification. I have used the same settings and updated in appsettings.json file in the WebHost project.

I have tried these scenarios.

  1. I didn't create the blobs and xml files, just gave the connection string to the container. I ran the application with different tenants and saw if they create them automatically. It didn't create any container or the blob files
  2. I have created the blobs and individual tenant containers as well. There are no Data protection keys that are getting stored in those files.
Piedone commented 1 month ago

I suggest you try first by removing everything unnecessary from your Program, and focus on getting this working. It works for all of our apps, so it's not like it's generally broken, but there's something specific to your application.

You can also check the logs, even after increasing the log level to Debug, and see if you can find anything useful.

github-actions[bot] commented 1 month ago

We triaged this issue and set the milestone according to the priority we think is appropriate (see the docs on how we triage and prioritize issues).

This indicates when the core team may start working on it. However, if you'd like to contribute, we'd warmly welcome you to do that anytime. See our guide on contributions here.

github-actions[bot] commented 1 month ago

It seems that this issue didn't really move for quite a while despite us asking the author for further feedback. Is this something you'd like to revisit any time soon or should we close? Please reply.

github-actions[bot] commented 3 weeks ago

Closing this issue because it didn't receive further feedback from the author for very long. If you think this is still relevant, feel free to reopen it with the requested details.