Search code examples
amazon-ecsaws-fargateamazon-elbasp.net-core-6.0azure-authentication

ASP.NET 6: Azure AD Authentication Infinite redirect loops with AWS Network LB and Fargate


I have a AWS Network Load balancer setup with a TLS (:443) Listener that forwards to a Target Group that is listening on port 8080.

The Target Group is an IP Type that points to a Fargate ECS instance.

My problem is that on that ECS instance my website is using Azure Ad for Auth. I got past the issue of the Redirect URI being HTTP instead of HTTPS, but now I am in a redirect loop that eventually ends in

We couldn't sign you in. Please try again.

I am using .NET 6 and Visual Studio 2022.

The Azure AD Auth was added via using the Connected Services in VS 2022.

The NLB URL has been added to Redirect URIs for the App in Azure AD.

Any help is appreciated.

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "xxxxxxxxx.com",
    "TenantId": "xxxxxxxxxx",
    "ClientId": "xxxxxxxxxx",
    "CallbackPath": "/signin-oidc"
  },
  "MicrosoftGraph": {
    "BaseUrl": "https://graph.microsoft.com/v1.0",
    "Scopes": "user.read"
  }
}

program.cs

var builder = WebApplication.CreateBuilder(args);

var initialScopes = builder.Configuration["MicrosoftGraph:Scopes"]?.Split(' ');

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
        .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
            .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
            .AddInMemoryTokenCaches();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});

// Add services to the container.
builder.Services.AddRazorPages().AddMicrosoftIdentityUI();
builder.Services.AddScoped<IDynamoDBConnection, DynamoDBConnection>();

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;  
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear(); 
}); 

builder.WebHost.UseUrls("http://*:8080"); 

var app = builder.Build();

//This is what fixes the Http redirect URI issue. Problem is it causes a redirect loop
app.Use((context, next) =>
{
    context.Request.Scheme = "https";
    return next(); //return next(context);  //rewritten 8/19 8:23 no change
}); 

app.UseForwardedHeaders(); 

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

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

app.MapRazorPages();
app.MapControllers();

app.Run();

I have tried multiple browsers and the issue is the same.


Solution

  • I ran into this same issue and managed to resolve by adding the client secret to the appsettings.json.

    In the Azure portal, go to Active Directory -> App registrations -> your-app -> Certificates & secrets. Add a new client secret, copy the Value (not the Secret ID, I gave myself an extra headache making that mistake) and paste it into your appsettings Azure object like so:

    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "xxxxxxxxx.com",
        "TenantId": "xxxxxxxxxx",
        "ClientId": "xxxxxxxxxx",
        "CallbackPath": "/signin-oidc",
        "ClientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }