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();
}
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);
}
});