Identity Server and NGINX Ingress Controller in Kubernetes

Christopher Lenard
2 min readApr 2, 2019

--

Kubernetes Logo

Running Identity Server 4 in Kubernetes requires some setup work. You are likely exposing Identity Server using an ingress controller like NGINX. These are the necessary steps to get things working.

Find full example code for this article here.

Configure NGINX Ingress Controller

The NGINX ingress controller’s default configuration does not support the necessary header size Identity Server requires, so we need to change that. The NGINX ingress controller should already be using a Kubernetes config map resource. We need to add some data entries for it to override the default values. Edit the config map using

kubectl edit cm YOUR-INGRESS-CONFIG-MAP -n kube-system

Then add the following entries to configure NGINX.

proxy-buffer-size: "128k"
proxy-buffers: "4 256k"
proxy-busy-buffers-size: "256k"
client-header-buffer-size: "64k"
http2-max-field-size: "16k"
http2-max-header-size: "128k"
large-client-header-buffers: "8 64k"

If you do not see any change in the NGINX config, you can delete its pods to force the ingress controller’s replica set to recreate them with the new configuration.

Add ForwardedHeadersOptions Middleware

ASP.NET Core apps running behind a reverse proxy require special headers for forwarding. You can read all about it here. This is the relevant code you will need in Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseIdentity();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}

Change Identity Server Scheme to HTTPS

Skip this step if your cluster does not use TLS-termination at the ingress level.

Incoming requests to a Kubernetes cluster are TLS-terminated in the NGINX controller by default. This is because your internal cluster network is secure and termination reduces complexity. Identity Server returns the endpoint discovery document based on the scheme it is running in — in this case it is HTTP. You need to tell your clients to use HTTPS. You can override this by adding the following code to your HTTP pipeline.

app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});

That should be all. I spent a lot of time tracking down these three issues and wouldn’t want anyone else to needlessly go through the same thing. If you have any problems, let me know. I’m happy to help.

--

--