Multiple Entra App Proxies for different authentication requirements within the same app

Had to create an app proxy at work for one of the apps we wanted to publish externally. Easy peasy, we do this regularly. Create an Entra ID app proxy, set an external and internal URL, Entra ID authentication, etc.

However, with this one I encountered a strange issue which I finally tracked down over the course of yesterday and today.

The web app is Odoo (published via Docker) and while everything worked fine, one aspect of it kept failing. The app creates invoices, and when users view the HTML version of an invoice it displays fine, but the PDF version is all wonky. Fonts are messed up, colours not as what we’d expect, things like the logos are missing and so on.

If we change the pre-authentication above to “Passthrough” this works without a hitch!

Looking at the logs (docker logs --tail 10 --follow <container>) I could see a difference when things work (passthrough mode) vs when they don’t (entra ID authentication).

When it doesn’t work it looks like this:

But when it works I can see more lines:

So that’s probably why the PDF is messed up when it doesn’t work. Certain fonts and CSS files are not being loaded.

There’s an option to see the invoice as an HTML report too, and that too gave a similar impression of there being other files at play.

The HTML version worked fine in both passthrough and Entra ID mode, while PDF only worked in passthrough. Why? All the URLs above were accessible from my browser in both modes too, so it wasn’t like any of them were getting blocked in either mode.

After a lot of random poking around and going through the various files and folders in the containers to get an idea of what might be happening, I came to the conclusion that it looks like the Odoo app creates an HTML version of an invoice first, and then converts it to PDF using a tool like wkhtmltopdf. I am not a 100% but I also found other tools like pdfjs too, so maybe its using those instead. Either ways, it seemed like the PDF is generated from the HTML version rather than somehow directly being created (which is what I was thinking when I started looking into it). That also explained the log entries – when the HTML file was created in the background, in the scenario where it works the web server has “hits” to the /web/content and so on URLs but in the scenarios that it doesn’t, the web server doesn’t even see these requests.

From there I concluded what was happening is that when I view the HTML version of the invoice from my computer all these /web/content and so on URLs work because I am SSO-ing into them even though they are behind Entra ID. But when these requests come from within the application itself, Entra ID blocks them and that’s why the requests fail and the application never seems them. So the resulting HTML is messed up, resulting in the PDF being messed up. When we use passthrough, these requests work and so the PDF is good.

These /web/content and so on URLs are public URLs. They are not behind any authentication from the application or web server itself, but by putting them behind Entra ID authentication we are introducing that and messing up the flow.

So what I need is for a way to have specific URLs not be under Entra ID authentication. They all need to be application proxies, but the pre authentication varies.

Here’s what I did.

First, a recap of the existing app proxy:

I went ahead and created a new one, with the same external URL hostname as the existing one but with some extra stuff added to the internal URL.

And I sent it to Passthrough. I repeated the same for the other URLs.

I have a total of 4 eventually.

Hopefully I haven’t missed any others, but with these 4 app proxies in place the PDF now generates correctly! I can keep the main app under Entra ID authentication and leave the ones that are public in passthrough mode.

This was a fun exercise!  And I got to poke around in Docker and Linux after a long long time too. 😃