ASP.NET Core 2.0, Kubernetes, https missing in reply address?

4/13/2018

I have an ASP.NET Core 2.0 web application deployed to a Kubernetes cluster. The application is using Azure AD for authentication to some protected pages. The Kubernetes cluster is setup with a Nginx ingress controller and Let's encrypt to support https.

I can access https://x.eastus.cloudapp.azure.com with no problem and by clicking on a link on the site I'm directed to https://x.eastus.cloudapp.azure.com/link, also with no problems.

But, when I click on a link, which requires a logged in user, I get:

Sign in
Sorry, but we’re having trouble signing you in.

AADSTS50011: The reply address 'http://x.eastus.cloudapp.azure.com/signin-oidc' does not match the reply addresses configured for the application: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'. More details: not specified

Note that URL above misses https and that is the problem.

I have registered "https://x.eastus.cloudapp.azure.com/signin-oidc" as a reply URL for the application in Azure AD.

But, I don't understand why the reply url used when logging in is missing https.

If I deploy the exact same application to an Azure Web App, I don't get this problem.

What could be the issue?

This is my Ingress YAML file:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: x-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    # Add to generate certificates for this ingress
    kubernetes.io/tls-acme: 'true'
spec:
  rules:
    - host: x.eastus.cloudapp.azure.com
      http:
        paths:
          - path: /
            backend:
              serviceName: x-service
              servicePort: 80
  tls:
    # With this configuration kube-lego will generate a secret called `x-tls-secret`
    # for the URL `x.eastus.cloudapp.azure.com`
    - hosts:
        - "x.eastus.cloudapp.azure.com"
      secretName: x-tls-secret

I have have the following code in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    });

    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });

    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddAzureAd(options => Configuration.Bind("AzureAd", options))
    .AddCookie();

    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseForwardedHeaders();

    app.UseStaticFiles();

    app.UseAuthentication();
}
-- OlavT
asp.net-core
azure-active-directory
kubernetes
kubernetes-ingress
nginx

1 Answer

11/13/2018

Add a custom Middleware in the Configure method to perform the manual http-https redirection

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps || context.Request.Headers["X-Forwarded-Proto"] == Uri.UriSchemeHttps)
    {
        await next();
    }
    else
    {
        string queryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : string.Empty;
        var https = "https://" + context.Request.Host + context.Request.Path + queryString;
        context.Response.Redirect(https);
    }
});
-- Natthapol Vanasrivilai
Source: StackOverflow