title: Endless circular redirect with IdentityServer4
body: <p>I'm developing multi-tenant ASP.NET MVC application using <strong>Finbuckle.Multitenant</strong> and <strong>IdentityServer4</strong> (using standard classes and controllers from their tutorials). My app uses route strategy for tenants (<a href="https://host/tenant1/controller/action" rel="nofollow noreferrer">https://host/tenant1/controller/action</a>) and I use separate cookies for each tenant (cookie named <em>auth.tenant1</em>, <em>auth.tenant2</em>... etc.) Everything works fine unless I specify custom Path for auth cookie. If all of them has <em>Path=/</em> everything is ok. BUT when I set <em>Path=/tenant1</em> to cookie named auth.tenant1 and the same pattern for every other tenants I have a circular redirects after passing consent screen. When I click "yes" on consent screen I got 302 challenge redirect from IdentityServer middleware on client side. It redirects me back to Consent screen. After each "yes" I'm returning to consent. However it happens only during authentication process. If I open new tab and head to <a href="https://host/tenant1" rel="nofollow noreferrer">https://host/tenant1</a> I won't be redirected and will be successfully authenticated.
  Googled for answers for days but haven't found any solutions. Please help me!</p>
  
  <p>Here is my client's <strong>Startup.cs</strong>:</p>
  
  <pre><code>    public void ConfigureServices(IServiceCollection services)
      {
          services.AddMvc();
  
          JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
  
          services.AddMultiTenant().WithInMemoryStore(Configuration.GetSection("MultiTenant:InMemoryStore"))
              .WithRouteStrategy(MapRoutes)
              .WithRemoteAuthentication()
              .WithPerTenantOptions&lt;AuthenticationOptions&gt;((options, tenantContext) =&gt;
              {
                  // Allow each tenant to have a different default challenge scheme.
                  if (tenantContext.Items.TryGetValue("ChallengeScheme", out object challengeScheme))
                  {
                      options.DefaultChallengeScheme = (string)challengeScheme;
                  }
              })
              .WithPerTenantOptions&lt;CookieAuthenticationOptions&gt;((options, tenantContext) =&gt;
              {
                  options.Cookie.Name += tenantContext.Identifier;
                  options.Cookie.Path = "/" + tenantContext.Identifier;
                  options.LoginPath = "/" + tenantContext.Identifier + "/Home/Login";
              });
  
          services.AddAuthentication(options =&gt;
          {
              options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
              options.DefaultChallengeScheme = "oidc";
          })
          .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =&gt;
              {
                  o.Cookie.Name = "auth.";
              })
          .AddOpenIdConnect("oidc", options =&gt;
          {
              options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
              options.Authority = "https://localhost:5000";
              options.RequireHttpsMetadata = true;
  
              options.ClientId = "mvc";
              options.SaveTokens = true;
  
              options.ClientSecret = "secret";
              //Hybrid protocols (OpenId + OAuth)
              options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
  
              options.GetClaimsFromUserInfoEndpoint = true;
              //ask to allow access to testApi
              options.Scope.Add("testApi");
              //allows requesting refresh tokens for long lived API access
              options.Scope.Add("offline_access");
  
              options.Events = new OpenIdConnectEvents()
              {
                  OnRedirectToIdentityProvider = ctx =&gt;
                  {
                      var tenant = ctx.HttpContext.GetMultiTenantContext()?.TenantInfo?.Identifier;
                      ctx.ProtocolMessage.AcrValues = $"tenant:{tenant}";
                      return Task.FromResult(0);
                  }
              };
          });
      }
  
      private void MapRoutes(IRouteBuilder router)
      {
          router.MapRoute("Default", "{__tenant__=tenant1}/{controller=Home}/{action=Index}/{id?}");
      }
  </code></pre>
  
  <p>Here is my client configuration on IdentityServer's side (appsettings.json): </p>
  
  <pre><code>{
    "clientId": "mvc",
    "clientName": "MVC Client",
    "allowedGrantTypes": [ "hybrid", "client_credentials" ],
    "clientSecrets": [
      { "value": "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" } // Sha256("secret")
    ],
    "redirectUris": [ "https://localhost:5002/signin-oidc" ],
    "postLogoutRedirectUris": [ "https://localhost:5002/signout-callback-oidc" ],
    "allowedScopes": [ "openid", "profile", "testApi" ],
    "allowOfflineAccess": true
  },
  </code></pre>
  
  <p>My IdentityServer4 config:</p>
  
  <pre><code>    public void ConfigureServices(IServiceCollection services)
      {
          services.AddMvc();
  
          var identityServerBuilder = services.AddIdentityServer()
              .AddDeveloperSigningCredential();
  
          if (_config.GetSection("AppSettings:UseDummyAuthentication").Get&lt;bool&gt;())
          {
              identityServerBuilder
                  .AddInMemoryIdentityResources(_config.GetSection("IdentityResources"))
                  .AddInMemoryApiResources(_config.GetSection("ApiResources"))
                  .AddInMemoryClients(_config.GetSection("Clients"))
                  .AddTestUsers(_config.GetSection("TestUsers"));
          }
  
          services.AddAuthentication();
      }
  </code></pre>
  
  <p>Please help me, guys! How can I make Path=/tenant1 scheme work without redirects on consent screen???</p>