'Authentication with Azure AD redirect_uri is incorrect using FrontDoor

I've got an Azure FrontDoor setup as a reverse proxy/load balancer between a container running on port 5443 and a custom domain. The point of this is to provide a standard address to users. I.e. container.azurecontainer.io:3443 is being pointed to by https://oursite3.example.com.

The same aci is running multiple containers:


    container.azurecontainer.io:443
    container.azurecontainer.io:2443
    container.azurecontainer.io:3443


    https://oursite1.example.com
    https://oursite2.example.com
    https://oursite3.example.com 

(line 116: BuildRedirectUri

We've then got multiple aci's deployed globally in different regions (hence using Frontdoor for loadbalancing between the different instances).

In this example, container.azurecontainer.io:3443 has MS AD auth installed on it. On clicking a link, a user gets a redirected to signin and a link gets produced and redirects the browser to it. The link has redirect_uri in it. Something like: https://login.microsoftonline.com/00000000-0000-0000-0000-000000000001/oauth2/authorize?client_id=00000000-0000-0000-0000-000000000002&redirect_uri=https%3A%2F%2Foursite3.example.com%3A3443%2Fsignin-oidc&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=jkalksdfj alskdjflkjalksdfjalkjA&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0

However, on sign in, the user gets the following on the site:

AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: '00000000-0000-0000-0000-000000000003'

The reason for this is that the AD application's reply url is set to:

https://oursite3.example.com/signin-oidc

However, on closer inspection the url that's the user was redirected to for signin includes this as a redirect_uri:

https://oursite3.example.com:5443/signin-oidc

i.e. port 5443 has been added to the end of the hostname.

Essentially it's including the underlying original port in the redirect_uri, which I'm not expecting it to.

I've tried using ForwardedOptions in our site. For example, our startup.cs file has the following in it (ConfigureServices):

            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                                           ForwardedHeaders.XForwardedProto;
                // Only loopback proxies are allowed by default.
                // Clear that restriction because forwarders are enabled by explicit 
                // configuration.
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
            });

followed by (Configure):

             app.UseForwardedHeaders();

This doesn't fix the issue.

I've had a look to see if I can override the value that's getting set to redirect_uri by looking here: https://github.com/dotnet/aspnetcore/blob/b7e122fbac4207b003dc07f6101e50218be8ff21/src/Security/Authentication/Core/src/AuthenticationHandler.cs

I've also tried this: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1#troubleshoot

and this:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1#nginx-configuration

Anyone know what else could be wrong?

thanks



Solution 1:[1]

When the Web App sits behind Azure Front Door, we need to configure the redirect_uri in the /authorize request to be the the Front Door's address.

In the code below we override the "OnRedirectToIdentityProvider" event and inject the Front Door's address. When I was trying this out I simply hardcoded the address but ideally you'd extract it from the headers that Front Door injects into the request.

This is the code I used when trying to authenticate my Blazor Server App (.net 6) runnning on an Azure App Service, Protected by Azure AD, running behind Azure Front Door.

public void ConfigureServices(IServiceCollection services)
{
    // ... existing code

    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                .EnableTokenAcquisitionToCallDownstreamApi(new[] { "User.Read" })
                .AddInMemoryTokenCaches();

    services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
    {
        options.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = (context) =>
            {   
                // Override the redirect_uri
                //  Ideally extract this from config 
                //  Or context.Request.Headers["X-Forwarded-Host"]
                //  see: https://docs.microsoft.com/en-us/azure/frontdoor/front-door-http-headers-protocol#front-door-to-backend

                context.ProtocolMessage.RedirectUri 
                    = "https://YOUR-FRONT-DOOR-or-APP-GATEWAY/signin-oidc";
                return Task.FromResult(0);
            }
        };
    });

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

    // ... existing code
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ... existing code
    
    // Don't forget to add this ...
    app.UseForwardedHeaders();
    
    // ... existing code
}

When the code works, the "redirect_uri" param should point to your Front Door/Gateway as shown here.

enter image description here

Hope that helped. ??

Solution 2:[2]

We've decided to separate the containers into different container instances. Makes for a simple design.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rohit L
Solution 2 ossentoo