DuendeSoftware / Support

Support for Duende Software products
20 stars 0 forks source link

Duende Identity Server with Azure Kubernetes Service - State Error #1247

Closed punitganshani closed 3 months ago

punitganshani commented 3 months ago

We are trying to integrate Duende IdentityServer 7 in Azure Kubernetes Service and are using Data Protection as per below in ASP.NET

        private static void RegisterDataProtection(IServiceCollection services)
        {
                     services.AddDataProtection()
                       .SetApplicationName("IHD")
                       .PersistKeysToDbContext<DataProtectionKeysContext>();

        }

At the backend, we have Azure SQL and we have verified storage of key in the database. For the purpose of scale, number of replica's are kept to 3 in Azure Kubernetes Service with 'hpa' to allow auto-scale to '10'.

For Ingress, we have added following annotations,

    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/body-size: 1024m
    nginx.ingress.kubernetes.io/client-body-buffer-size: 50m
    nginx.ingress.kubernetes.io/client-max-body-size: 50m
    nginx.ingress.kubernetes.io/proxy-body-size: 1024m
    nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
    nginx.ingress.kubernetes.io/proxy-buffering: 'on'
    nginx.ingress.kubernetes.io/proxy-buffers-number: '8'
    nginx.ingress.kubernetes.io/server-snippet: |
      client_header_buffer_size 100k;
      large_client_header_buffers 4 100k;

Upon login process, we get the error Unable to unprotect the message.State

When we reduce the number of replicas to 1, the application runs correctly. This means the Duende IdentityServer can't load balance. We have verified the documentation here

What are we missing?

josephdecock commented 3 months ago

This sounds like you probably have a call to AddOidcStateDataFormatterCache without adding an IDistributedCache that all nodes can share. Either remove the call to AddOidcStateDataFormatterCache or add a distributed cache (e.g., redis).

The state data cache moves some state out of the query parameters and stores it server side. This is necessary in some federation scenarios where the url can otherwise get longer than is allowed by some networking infrastructure. We store the server side data in an IDistributedCache and by default register the in memory distributed cache. That is appropriate for local development, demos, and non-load balanced environments, but in your load balanced environment you will need a different distributed cache. You may not need the state data cache at all though, so consider that before you rush to add distributed cache to your architecture.

To make that decision, take a look at our documentation here where we discuss the state cache in detail.

RolandGuijt commented 3 months ago

@punitganshani Did this help you? If so I'd like to close.

RolandGuijt commented 3 months ago

Closing for now but feel free to reopen if the need is there.