Auth0 Home Blog Docs

Bad Gateway running ASP.net Core app in Kubernetes and Auth0

I’m running a ASP.NET core basic app that uses auth0 authentication (getting started example), it works perfect locally, as soon as I try to run it behind an ingress controller (NGINX) in kubernetes , when it calls “signin-auth0” handler, NGINX is giving a 502 (Bad Gateway error).

Auth0 Log says it is a successfull authentication, but app fails

Can you provide sample code showing your authentication routine minus any sensitive details so we can investigate?

application code is almost identical to the getting started example for asp.net core:

startup.cs includes:

public void ConfigureServices(IServiceCollection services) {
            services.Configure<CookiePolicyOptions>(options => {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            // Add authentication services
            services.AddAuthentication(options => {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect("Auth0", options => {
                // Set the authority to your Auth0 domain
                options.Authority = $"https://{Configuration["Auth0:Domain"]}";

                // Configure the Auth0 Client ID and Client Secret
                options.ClientId = Configuration["Auth0:ClientId"];
                options.ClientSecret = Configuration["Auth0:ClientSecret"];

                // Set response type to code
                options.ResponseType = "code";

                // Configure the scope
                options.Scope.Clear();
                options.Scope.Add("openid");

                // Set the callback path, so Auth0 will call back to http://localhost:5000/signin-auth0
                // Also ensure that you have added the URL as an Allowed Callback URL in your Auth0 dashboard
                options.CallbackPath = new PathString("/signin-auth0");

                // Configure the Claims Issuer to be Auth0
                options.ClaimsIssuer = "Auth0";

                // Saves tokens to the AuthenticationProperties
                options.SaveTokens = true;

                options.Events = new OpenIdConnectEvents {
                    // handle the logout redirection
                    OnRedirectToIdentityProviderForSignOut = (context) => {
                        var logoutUri = $"https://{Configuration["Auth0:Domain"]}/v2/logout?client_id={Configuration["Auth0:ClientId"]}";

                        var postLogoutUri = context.Properties.RedirectUri;
                        if (!string.IsNullOrEmpty(postLogoutUri)) {
                            if (postLogoutUri.StartsWith("/")) {
                                // transform to absolute
                                var request = context.Request;
                                postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
                            }
                            logoutUri += $"&returnTo={ Uri.EscapeDataString(postLogoutUri)}";
                        }

                        context.Response.Redirect(logoutUri);
                        context.HandleResponse();

                        return Task.CompletedTask;
                    },
                    OnRedirectToIdentityProvider = context =>
                    {
                        context.ProtocolMessage.SetParameter("audience", "https://api.solucionesenlinea.com");
                        context.ProtocolMessage.SetParameter("scope", "openid email");

                        context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase);

                        return Task.FromResult(0);
                    }
                };
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            } else {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseMvc(routes => {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

on the kubernetes side, deployment is very straight forward:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: shootingrangelog-deployment
spec:
  selector:
    matchLabels:
      app: shootingrangelog
  replicas: 1
  template:
    metadata:
      labels:
        app: shootingrangelog
    spec:
      containers:
      - name: shootingrangelog
        image: [registry name]/[ImageName]:{BuildId}
        env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "Development"
        - name: Node_Name
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        ports:
        - containerPort: 80
      imagePullSecrets:
        - name: [secretName]
      
---

apiVersion: v1
kind: Service
metadata:
  name: shootingrangelog-service
spec:
  selector:
    app: shootingrangelog
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: shootingrangelog-root-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - myapp.mysite.com
    secretName: [secretName]
  rules:
  - host: myapp.mysite.com
    http:
      paths:
      - path: /
        backend:
          serviceName: shootingrangelog-service
          servicePort: 80

I’m guessing it is because of the NGINX ingress controller (load balancer) since when I run 1 instance locally directly it works fine

Can you try configuring ASP.Net Core to use the load balancer’s forwarded-for headers as explained in this response?

@wedelthomas I wanted to follow up and see if you have been able to try the changes Nicolas suggested above? Please let us know if you have any questions we can assist with on this subject.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.