0

I'm using OpenID authentication. When I have several app services from different regions inside Traffic Manager, I get above error regarding the state of authentication. It occures even when I use this code :

    private async Task ConfigureDataProtection(IServiceCollection services)
    {
        var container = "container";
        var relativePath = "folder/keys.xml";
        var connectionString = Configuration.GetSection("ConnectionStrings:AzureConnectionString").Value;
        var storageAccount = CloudStorageAccount.Parse(connectionString);
        await EnsureContainerExists(storageAccount, container);
        services.AddDataProtection().PersistKeysToAzureBlobStorage(storageAccount, relativePath);
    }

When I host horizontally scaled app services from one region, everything works fine. I'm using Azure. Why can this issue occur?

  • See following posting : https://stackoverflow.com/questions/72010688/asp-net-core-3-1-unable-to-unprotect-the-message-state-running-in-debugger?force_isolation=true – jdweng Apr 03 '23 at 13:52
  • @jdweng I've already seen that. However, it is still not working for me, as I described – Maksym Shuldiner Apr 03 '23 at 14:07
  • Is everybody using the same account? What should happen is the service should detect the remote end point and treat each end point separately. I think the service only checking the account (or group) and when it is seeing two logins from same account creating an error. The following may help : https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/how-to-manage-groups?force_isolation=true – jdweng Apr 03 '23 at 14:46
  • @jdweng I'm using our own login server, not Azure AD – Maksym Shuldiner Apr 03 '23 at 14:54
  • It is still Azure Authentication. Just using a different server for credentials. See : https://learn.microsoft.com/en-us/azure/service-bus-messaging/message-sessions?force_isolation=true – jdweng Apr 03 '23 at 14:57
  • @jdweng the scope of discussion is Azure Traffic Manager, I guess Service Bus is not related – Maksym Shuldiner Apr 03 '23 at 14:59
  • I would think a login is a Message just like any other message. Service Bus is the processing of messages. – jdweng Apr 03 '23 at 15:08

1 Answers1

0

The error unable to unprotect the message.state when using Azure Traffic Manager you are getting is due to the data protection mechanism used by ASP.NET Core.

While using OpenID authentication with multiple instances of app service running in different regions behind Azure Traffic Manager, the data protection keys used to encrypt and decrypt the authentication state are not in synchronize across all instances. Hence this causes the error.

One solution is to use a centralized data protection approach that allows all instances of the app service to share duplicate data protection keys. This can be done by using Azure Blob Storage to store the data protection keys, as you are already doing in your code.

Add DataProtectionProvider as mentioned in Github.

Thanks @ jkotalik for the GitHub Code.

options.DataProtectionProvider = options.DataProtectionProvider ?? _dp;

    if (string.IsNullOrEmpty(options.SignOutScheme))
     {
          options.SignOutScheme = options.SignInScheme;
     }

    if (options.StateDataFormat == null)
      {
           var dataProtector = options.DataProtectionProvider.CreateProtector(
           typeof(OpenIdConnectHandler).FullName, name, "v1");
           options.StateDataFormat = new PropertiesDataFormat(dataProtector);
      }

If you use multiple OIDC middleware, you must set a unique CallbackPath for each.

For further information refer to SO link

Sourav
  • 814
  • 1
  • 9
  • Hm, so AddDataProtection is not enough? I should add this code while adding OpenId? – Maksym Shuldiner Apr 06 '23 at 08:22
  • I have only one oidc connector – Maksym Shuldiner Apr 06 '23 at 08:42
  • thanks for your answer, would be glad if we can discuss that further – Maksym Shuldiner Apr 06 '23 at 11:25
  • Yes, adding `AddDataProtection` is not enough when multiple instances of app service running in different regions behind Azure Traffic Manager.  And also you need to check that all instances of your app service are using the same data protection keys. – Sourav Apr 06 '23 at 11:57
  • You can achieve this by configuring your app service instances to use the same Azure Blob Storage container and key file. You can do this by setting the `DataProtection:BlobStorage:ContainerName` and `DataProtection:BlobStorage:RelativePath` configuration values to the same values in all instances of your app service.   Since you have only one OpenID Connect connector, you can use the same data protection keys for all instances of your app service. – Sourav Apr 06 '23 at 11:58
  • hm, but they already use the same blob storage file – Maksym Shuldiner Apr 06 '23 at 12:29
  • and so what should I add to the code? I guess if I use AddDataProtection() it just alters the default IDataProtectionProvider that is used further in OpenIdConnectPostConfigureOptions. All App Services already use the same container name and relative path. what is the overall purpose of creating custom DataProtectionProvider? the thing that only change is the name of data protector : – Maksym Shuldiner Apr 06 '23 at 12:36
  • the code that I posted is already on prod. So all the App Services share the same Blob storage key. However, it is not working – Maksym Shuldiner Apr 06 '23 at 12:42