title: IdentityServer4 - sub claim is missing
body: <p>I've got an IdentityServer4 instance that I'm trying to get running in a Docker container behind an nginx proxy. I've based it on the AspNet identity sample from the Git repo, but after a user successfully registers a new account I get "An error occurred" from IdentityServer and the logs show</p>
  
  <p><code>[07:46:39 ERR] An unhandled exception has occurred: sub claim is missing
  System.InvalidOperationException: sub claim is missing
     at IdentityServer4.IdentityServerPrincipal.AssertRequiredClaims(ClaimsPrincipal principal
     at IdentityServer4.Hosting.IdentityServerAuthenticationService.AugmentPrincipal(ClaimsPrincipal principal
     at IdentityServer4.Hosting.IdentityServerAuthenticationService.&lt;SignInAsync&gt;d__7.MoveNext</code></p>
  
  <p>My Startup.cs looks like this</p>
  
  <pre><code>var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().
  var connectionString = Configuration.GetConnectionString("DefaultConnection");
  var issuerUri = Configuration.GetSection("IssuerUri").Value;
  
  services.AddDbContext&lt;ApplicationDbContext&gt;(options =&gt; 
      options.UseSqlServer(connectionString));
  
  services.AddIdentity&lt;ApplicationUser, IdentityRole&gt;()
      .AddEntityFrameworkStores&lt;ApplicationDbContext&gt;()
      .AddDefaultTokenProviders();
  
  services.AddTransient&lt;IEmailSender, EmailSender&gt;();
  
  services.AddMvc();
  
  services.AddCors(o =&gt; o.AddPolicy("CorsPolicy", b =&gt;
  {
      b.AllowAnyOrigin()
          .AllowAnyMethod()
          .AllowAnyHeader();
  }));
  
  services.AddIdentityServer(options =&gt;
  {
      options.IssuerUri = issuerUri;
      options.PublicOrigin = issuerUri;
  })
  .AddDeveloperSigningCredential()
  
  // this adds the config data from DB (clients, resources)
  .AddConfigurationStore(options =&gt;
  {
      options.ConfigureDbContext = builder =&gt;
          builder.UseSqlServer(connectionString,
              sql =&gt; sql.MigrationsAssembly(migrationsAssembly));
  })
  
  // this adds the operational data from DB (codes, tokens, consents)
  .AddOperationalStore(options =&gt;
  {
      options.ConfigureDbContext = builder =&gt;
          builder.UseSqlServer(connectionString,
              sql =&gt; sql.MigrationsAssembly(migrationsAssembly));
  
      // this enables automatic token cleanup. this is optional.
      //options.EnableTokenCleanup = true;
      //options.TokenCleanupInterval = 30;
  });
  </code></pre>
  
  <p>I must have missed some obvious config but I can't see where.  Any ideas?</p>
  
  <p><strong>UPDATE</strong>
  I've made some progress with this and seemed to have got past the initial error. The user is now authenticated but the signin-oidc page throws the error</p>
  
  <pre><code>[11:33:21 INF] Request starting HTTP/1.1 POST http://mvcportal.co.uk/signin-oidc application/x-www-form-urlencoded 1565
  [11:33:21 INF] AuthenticationScheme: Cookies signed in.
  [11:33:21 INF] Request finished in 684.8425ms 302
  [11:33:27 INF] Request starting HTTP/1.1 POST http://mvcportal.co.uk/signin-oidc application/x-www-form-urlencoded 1565
  [11:33:27 ERR] Message contains error: 'invalid_grant', error_description: 'error_description is null', error_uri: 'error_uri is null', status code '400'.
  </code></pre>
  
  <p>I've got a valid JWT but I notice the idp is not equal to the issuer. Is that correct?</p>
  
  <pre><code>{
    "nbf": 1508758474,
    "exp": 1508758774,
    "iss": "http://myproxiedlogonsitebehindnginx.co.uk",
    "aud": "mvc.portal",
    "nonce": "636443552746808541.MGVjMzk2NTEtYmYwNS00NmQwLTllOTQtZDVjNjdlYTA2YWVlYTQ3Zjg1NjgtZDA1Yi00NDE0LWJiYmYtMjM4YzI1NjZlYTcx",
    "iat": 1508758474,
    "c_hash": "kG7wG8vSgRe5zdriHQ6iMA",
    "sid": "c9410ee8f27b69c32e43d5ac3d407f37",
    "sub": "e80fb854-cab2-4381-8057-19de0fea73f4",
    "auth_time": 1508757008,
    "idp": "local",
    "amr": [
      "pwd"
    ]
  }
  </code></pre>
  
  <p><strong>UPDATE 2</strong>
  This is the client configuration on idsrv if that helps</p>
  
  <pre><code>new Client
  {
      ClientId = "mvc.portal",
      ClientName = "Customer Portal",
      ClientUri = customerPortalBaseUri,
  
      ClientSecrets =
      {
          new Secret("21f51463-f436-4a84-92ce-1b520dd63a81".Sha256())
      },
  
      AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
      AllowAccessTokensViaBrowser = false,
  
      RedirectUris = { $"{customerPortalBaseUri}/signin-oidc"},
      FrontChannelLogoutUri = $"{customerPortalBaseUri}/signout-oidc",
      PostLogoutRedirectUris = { $"{customerPortalBaseUri}/signout-callback-oidc" },
  
      AllowOfflineAccess = true,
  
      RequireConsent = false,
  
      AllowedScopes =
      {
          IdentityServerConstants.StandardScopes.OpenId,
          IdentityServerConstants.StandardScopes.Profile,
          IdentityServerConstants.StandardScopes.Email
      }
  }
  </code></pre>
  
  <p>And this is the client/portal config</p>
  
  <pre><code>services.AddAuthentication(options =&gt;
      {
          options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = "oidc";
      })
      .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
      .AddOpenIdConnect("oidc", options =&gt;
      {
          options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
          options.Authority = "http://myproxiedlogonsitebehindnginx.co.uk";
          options.RequireHttpsMetadata = false;
          options.ClientId = "mvc.portal";
          options.ClientSecret = "21f51463-f436-4a84-92ce-1b520dd63a81";
          options.ResponseType = "code id_token";
          options.SaveTokens = true;
          options.GetClaimsFromUserInfoEndpoint = true;
      });
  </code></pre>
  
  <p><strong>UPDATE 3</strong>
  So now I'm convinced it has something to do with the deployment, because if I run the mvc app on my local machine but use the deployed idsvr in the container (behind nginx) I can authenticate without a problem, however if I try the version of the containerised portal I still get an unhandled 500 without it being logged and then if I retry the action I get this logged:</p>
  
  <pre><code>[11:22:51 INF] Request starting HTTP/1.1 POST http://mvcportal.co.uk/signin-oidc application/x-www-form-urlencoded 1559
  [11:22:51 ERR] Message contains error: 'invalid_grant', error_description: 'error_description is null', error_uri: 'error_uri is null', status code '400'.
  [11:22:51 ERR] Exception occurred while processing message.
  Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_grant'], error_description: 'error_description is null', error_uri: 'error_uri is null'.
  </code></pre>