Using AAD B2C with an Application Gateway (/with Kubernetes) not working => 404

512 Views Asked by At

Architecture
Our web-applications are being deployed to our kubernetes cluster which are being integrated in our application gateway via the ingress extension (Azure Gateway ingress). If you navigate to the web-application, you need to sign-in and authenticate via configured app registration in our AAD B2C.

The web-application itself is being hosted on port 80 in our kubernetes cluster, but will be accessible via https within our application gateway. The application gateway will have the necessary certificates and so on. The docker-compose (deployment of the pods) have enabled the environment variable "FORWARDING_HEADERS".

The AAD B2C does have the correct redirect URIs configured.

Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews(options =>
                {
                    var policy = new AuthorizationPolicyBuilder()
                        .RequireAuthenticatedUser()
                        .Build();
                    options.Filters.Add(new AuthorizeFilter(policy));
                }).AddMicrosoftIdentityUI()
               .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null)
               .AddDapr();

            services.AddCookiePolicy(options =>
            {
                options.Secure = CookieSecurePolicy.Always;
                options.MinimumSameSitePolicy = SameSiteMode.None;
                options.HandleSameSiteCookieCompatibility();
            });
            
            services.UseCoCoCore()
                .UseCoCoCoreBootstrapper<CoreComponent>()
                .UseCoCoCoreBootstrapper<UiComponent>()
                //the following line is registering the AuthComponent, see below for more details
                .UseCoCoCoreBootstrapper<UiAuthComponent>();
        }

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, ILog logger)
        {
            loggerFactory.AddSerilog(logger.GetLogger(), dispose: true);
            if (!env.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

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

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

AuthComponent.cs It is basically this


public void RegisterAuthorization(IConfiguration configuration, string configSectionName, string[] intialScopes)
        {
            _serviceCollection.AddMicrosoftIdentityWebAppAuthentication(configuration, configSectionName)
                .EnableTokenAcquisitionToCallDownstreamApi(intialScopes)
                .AddInMemoryTokenCaches();

            _serviceCollection.AddAuthorization(options =>
                {
                    options.AddPolicy("IsGroupMember",
                        policy => { policy.Requirements.Add(new IsGroupMemberRequirement()); });
                }););
        }

I am using a configuration with this properties

{
  "AzureAdB2CConfig": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "myAaadB2c.onmicrosoft.com",
    "ClientId": "<client-id>",
    "TenantId": "<tenant-id>",
    "ClientSecret": "<client-secret>",
    "CallbackPath": "/myapp/signin-oidc"
  }
}

What I expect
Navigating to our https://custom.domain.com/myapp/ should allow me to authenticate myself and forward to the desired entry point of my web-application, e.g. https://custom.domain.com/myapp/Overview

What is actually happening?
The following scenarios are working without any problems:

  • Running the application on my machine via localhost.
  • Running the application in my kubernetes cluster, exposed via LoadBalancer, and accessing it via the public IP.

If I am navigating to the following url https://custom.domain.com/myapp/ , I am getting the HttpStatusCode 404. The 404 is about "/signin-oidc" which he cannot find. I have checked via my browser the header entries and it looks OK for me. The hostname of my header is also correct (custom.domain.com).

Additional info
Ingress configuration

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: myapp
  namespace: myapp-namespace
  annotations:
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: myCert
    appgw.ingress.kubernetes.io/backend-hostname: custom.domain.com
    appgw.ingress.kubernetes.io/backend-path-prefix: /
    appgw.ingress.kubernetes.io/cookie-based-affinity: 'true'
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  rules:
    - http:
        paths:
          - path: /myapp/*
            pathType: Exact
            backend:
              service:
                name: myapp-service
                port:
                  number: 80
1

There are 1 best solutions below

2
On

I have found the solution via https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-6.0

I added to my application the following code

app.Use((context, next) =>
{
    context.Request.PathBase = new PathString("/myapp");
    return next(context);
});

I also changed the callbackpath back to /signin-oidc