Multiple instance of one client in Identity server throw Exception

1/8/2020

In my project, I use the Identity server OpenId Connect for authorization.

One of the clients of Identity is the MVC type.

For scalability, I need multiple replicas of the client running.

When the number of the client is 1 (only one instance is running), all things are great.

When increase number of client to 2, after deployment when browsing pages that need authorization

  1. Redirect to the Identity server (as I expected)
  2. After login successful, Identity set cookies in the Identity server domain(as I expected)
  3. I have expected that after redirect, MVC client cookies set in the client domain and user authorized, But this exception is thrown:

Exception: Unable to unprotect the message.State.

Unknown location

Exception: An error was encountered while handling the remote login.

MVC client OpenIdConnect settings:

"OpenIdConnect": {
    "ClientId": "mvc",
    "Authority": "https://identity.usw1.kubesail.io/",
    "ClientSecret": "REDACTED",
    "ResponseType": "code",
    "UsePkce": false,
    "GetClaimsFromUserInfoEndpoint": true,
    "SaveTokens": false,
    "RequireHttpsMetadata": false,
    "Scope": [ "openid", "profile" ],
}

Identity server setting for MVC Client

new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",

    AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
    RequirePkce = false,
    ClientSecrets = { new Secret("REDACTED".Sha256()) },

    RedirectUris = { "http://mvc.c1.kubesail.io/signin-oidc" },
    FrontChannelLogoutUri = "http://mvc.c1.kubesail.io/signout-oidc",
    PostLogoutRedirectUris = { "http://mvc.c1.kubesail.io/signout-callback-oidc" },
    RequireConsent = false,

    AllowOfflineAccess = true,
    AllowedScopes = { "openid", "profile" }
}

Specification of development and deployment:

Identity server 4

Project types are Asp.net core 3.1

Deployment on Kubernetes

-- Mohammad Akbari
asp.net-core
identityserver4
kubernetes
openid-connect

1 Answer

1/9/2020

You need sticky session [link] on your LoadBalancer or Ingress as I see you're using Kubernetes.

With sticky session, the first time a user accesses your application the ingress controller sets a cookie and maps the value of the cookie with a pod. Every time the user "talks" with your application or makes any other request, the ingress service can read this cookie and always redirect you to the same Pod.

The problem without the sticky session is that some of the requests will hit one pod and some will hit the other, as the state is not shared among the different client instances, it can't complete the flow.

BTW: please do not share your client secret!

-- Pablo Recalde
Source: StackOverflow