SINGLE SIGN ON AZURE CONTAINER APPS (EASY-AUTH)
Je hoort deze kreet steeds vaker: “Single Sign-On”. Eén keer inloggen met jouw account om vervolgens toegang te verkrijgen tot meerdere apps zonder opnieuw te hoeven inloggen. Eén van de bekendste voorbeelden is office365 van Microsoft. Maar hoe zit dat nu voor je eigen applicaties? In deze blog laten we je zien hoe je SSO kunt inzetten voor Azure Container Apps. Hierbij maken we gebruik van de “Easy-auth” methode voor authenticatie en autorisatie.
Er is een aantal voorwaardelijkheden waarvan we in deze blog uit mogen gaan dat ze bestaan. Er is een tenant (Azure Entra ID) met accounts. Er is een Azure subscription gerealiseerd waarin de demo vrij gebouwd kan worden zonder daarbij de huidige productie in de weg te zitten (noem het een sandbox account). Een resource group bestaat en er zijn 1 of meerdere docker images beschikbaar die gebruikt kunnen worden om een Azure Container App mee op te spinnen.
DESIGN
In onderstaande schema staat het design wat voor deze opstelling gebruikt is.
Alle resources zijn publiekelijk beschikbaar m.u.v. de KeyVault en UAMI (User Assigned Managed Identity). Noem het een “Open” methode. Reden hiertoe is omdat het gaat om een proof of concept voor SSO op Azure Container Apps. In de echte wereld zorg je er natuurlijk voor dat je de resources in een eigen vnet / subnet implementeert zijn met private endpoints. Daarnaast implementeer je een publieke loadbalancer zoals app gateway om als ingang te dienen naar de container environment.
REALISATIE
In de container registry upload je één of meerdere docker images om vanuit daar een container op te kunnen spinnen. Zorg ervoor dat de UAMI de role assignment ‘AcrPull’ toegewezen krijgt, zodat de Azure Container App images kan lezen uit deze container registry.
De Container App Environment is een landingsplek voor de Azure Container Apps. Hierin bestaat de keuze uit dedicated resources of pay-as-you-go. Voor deze blog volstaan we met een pay-as-you-go methode. Je betaalt alleen de compute resources die je daadwerkelijk gebruikt.
Dan is het tijd om een Container App op te spinnen. Azure Container Apps stelt je in staat om je container images te hosten en is een serverless oplossing. Het kan dus terug schalen naar 0 indien deze niet gebruikt wordt. Gezien we gekozen hebben voor een pay-as-you-go methode, betalen we dan ook niets. Penalty is wel zodra de container app naar 0 is terug geschaald, de image eerst opnieuw moet opstarten zodra je deze benaderd. Dat kost tijd.
Geef bij het aanmaken van de Container App de juiste registry op, vervolgens zet je de UAMI als user assigned identity op in de resource. Selecteer het juiste image en tag en selecteer dat je gebruik maakt van de UAMI om in te loggen naar de container registry. Als laatste zorg je ervoor dat de target poort van de ingress op de TCP-poort staat waarmee de container image bereikbaar is. Er zijn nog tal van opties in te stellen, maar voor deze SSO-demo laten we die buiten beschouwing.
START DE APPLICATIE
De container app kan worden gestart. Azure verzorgt voor jou een
containeromgeving waarin jouw image wordt geladen.
Wanneer de service bereikbaar is, ziet het schematisch er zo uit:
Azure verzorgt voor jou een publieke endpoint van de Container App waarop jij de applicatie kunt benaderen. Dit komt omdat er voor een publieke methode is gekozen. In dit voorbeeld is het een simpele webserver met een index file. Noem het een homepagina. Als je de endpoint benadert, krijg je keurig de indexfile te zien.
Dit is natuurlijk nog zonder authenticatie, en dus ook zonder SSO. Daarvoor moeten we nog wat implementeren op de Azure Container App.
IMPLEMENTATIE SSO VOOR DE CONTAINER APPLICATIE
Binnen Azure zijn er tal van mogelijkheden om SSO in te stellen. Voor deze blog hebben we gekozen voor de “Easy-auth” methode. Deze methodiek bestaat al geruime tijd voor de webapp resource binnen Azure. Sinds korte tijd is deze functie ook beschikbaar gekomen voor Azure Container Apps. Om deze in te stellen dien je in de “Authentication” sectie van de Azure Container App op “Add identity
Om deze functionaliteit te kunnen implementeren heb je wel een identity provider nodig. Dat kan zijn: google, x (twitter), facebook, GitHub, Apple en Open ID Connect. Maar ook Microsoft Entra, en laten we die toevallig hebben.
Binnen Entra maak je nu een Application Registration. Deze wordt als identity gebruikt om in te kunnen loggen naar je applicatie. In deze demo gebruiken we zoveel mogelijk de default waarden voor de configuratie van de Application Registration.
Wanneer je de authenticatie enabled op de Azure Container App, vindt er binnen Azure wat magie plaats. Azure verzorgt voor jou een middleware container die voor de afhandeling van de authenticatieflow zorgt. Schematisch ziet het er zo uit indien je wederom de publieke endpoint benaderd:
De gebruiker wordt nu omgeleid naar de Microsoft login pagina. Je voert jouw credentials in. Gezien we als voorwaarde hebben gesteld dat er een Entra omgeving moet zijn, mag je deze app benaderen. Default staat Azure alleen accounts toe die bij deze Entra omgeving horen (single tenant). Dan volgt MFA (Multi Factor Authentication) en wanneer die ook succesvol is, krijg je de eerdergenoemde homepagina weer te zien. Indien je nu een andere applicatie in dezelfde tenant benaderd die ook voorzien is van de “Easy-auth” methode, hoef je niet nog eens in te loggen. SSO is nu in place. Mocht je nu een applicatie hebben zonder UI (denk aan een API), dan dien je zelf de authenticatie flow te regelen in de code.
ZIJN WE NU KLAAR?
Je zou zeggen van wel. We kunnen inloggen naar de app, we krijgen keurig de homepagina te zien. En toch willen we meer uit SSO halen. Omdat de achterliggende techniek die gebruikt wordt door Microsoft om Single Sign-On te realiseren OIDC (Open ID Connect) is, kunnen we ook gebruik gaan maken van de user claims. Een van de methoden om deze te kunnen lezen is om de URL te voorzien van het suffix /.auth/me.
Ai, dat werkt niet helemaal… terwijl dit bij webapps wel werkt.
Dit is te verklaren omdat je voor deze functionaliteit gebruik moet maken van de tokenstore feature. Deze tokenstore staat voor Azure Container Apps uit. Sterker nog, deze feature is in preview. Dat wil zeggen, je kan het gebruiken in een demo opstelling maar in productie zult gij geen preview features gebruiken.
Toch willen we graag met de user claims aan de slag gaan, want deze informatie kun je verder verwerken in je app. Hoe verder?
REQUEST HEADERS GEBRUIKEN IN APPLICATIE OM USER CLAIMS OP TE HALEN
Gelukkig voor ons is er een andere methodiek om de user claims op te halen. Dat is door gebruik te maken van request headers die Microsoft voor jou ter beschikking stelt. Zie voor gedetailleerde uitleg de volgende link:
https://learn.microsoft.com/en-us/azure/container-apps/authentication#access-user-claims-in-application-code.
Om deze functionaliteit te bewijzen, maken we gebruik van de volgende request headers:
X-MS-CLIENT-PRINCIPLE-NAME en X-MS-CLIENT-PRINCIPAL-ID.
De applicatie aan de achterkant moet natuurlijk wel aangepast worden om deze gegevens op te halen. Maar in principe kan bijna elke programmeer/scripttaal overweg met headers. Zie hier het resultaat:
Nu we deze gegevens hebben kun je die verder in de applicatie gebruiken.
RESULTAAT
We hebben nu een publiek beschikbare Azure Container App gerealiseerd welke gebaseerd is op een Docker image en hebben we hierop SSO beschikbaar gemaakt door gebruik te maken van de “Easy-auth” methode. We kunnen beschikken over de user claims door gebruik te maken van request headers. Deze claims kunnen we vervolgens naar wens gebruiken in onze applicatie.