In deze blog laat ik je de stappen zien die je kunt volgen om een veiligere en flexibele flow voor het inloggen op Single Page Applications of Native Mobile apps te maken met de WSO2 Identity Server. Ik ga daarvoor eerst demonstreren hoe de interactie van de nieuwe flow tussen de verschillende componenten werkt en daarna leg ik de technische veranderingen uit die nodig zijn voor je app/webpagina om alles te laten werken!
Overstappen op autorisatiecodes + PKCE
Veel webbased applicaties gebruiken een IAM product en doen dat met een Implicit Grant in de inlog flow, terwijl Native Mobile Apps juist het Password Grant type benutten. Voor elk van deze benaderingen zijn er kwetsbaarheden gevonden en beschreven in OAUTH documenten 1 en 2.
Wat er op dit moment aangeraden wordt voor zowel native apps als webbased applicaties, is om over te stappen naar een autorisatiecode + PKCE flow. Deze combinatie wordt op dit moment gezien als best practice, maar het kost wel wat moeite aan de kant van de applicatie om over te stappen op deze flow. Met deze handleiding kan ik die transitie hopelijk net wat makkelijker voor je maken.
Een sequentiediagram van de nieuwe flow:
Vereiste wijzigingen van WSO2:
Als je een bestaande Service Provider geconfigureerd hebt voor de applicatie zoals in dit WSO2 artikel, dan hoef je alleen de “code” grant type in te schakelen en de checkbox “PKCE Mandatory” op aan te zetten. Je kunt als extra optie ook kiezen voor “Allow authentication without client secret”, zodat je app of webpagina de geheime waarde van de WSO2 client niet hoeft te bewaren. Dit is de manier die het beste werkt als je autorisatiecodes met PKCE gebruikt.
Wil je jouw Identity and Access Management gelijk vanaf het begin goed regelen?
Nu downloadenWebbased applicaties (Single-Page-Applications):
Ik zal de belangrijkste verschillen van de nieuwe flow voor het inloggen, in vergelijking met de Implicit Grant flow, hieronder op een rijtje zetten.
- Iedere keer dat de pagina geladen wordt of dat er authenticatie vereist wordt, moet de applicatie backend
- een “code_verifier” genereren volgens https://tools.ietf.org/html/rfc7636#section-4.1 en onthouden (als deze nog niet bestond).
- de code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) berekenen. Je kunt deze website ter referentie gebruiken voor een valide conversie van een code_verifier string naar een code_challenge.
- Bij een impliciete flow roept de SPA applicatie (bijv. Angular) altijd het eindpunt van de Authorization Server (WSO2) “oauth2/authorize” aan, zodat WSO2 de gebruikerssessie kan valideren en indien nodig door kan verwijzen naar de inlogpagina. Dit aanroepen gebeurt ook in de nieuwe flow, maar met de volgende veranderingen.
- de “response_type” query parameterwaarde veranderd van van “id_token token” naar “code”
- Er moeten twee nieuwe parameters worden toegevoegd;
- code_challenge_method = S256
- code_challenge = calculated in difference #2
- In de impliciete flow ontvangt de application het ID-token als een URL-fragment (bijv. http://app.com#id_token=JWT). In de nieuwe flow, zal WSO2 een ‘code‘ als een query parameter teruggeven en moet de applicatie backend vervolgens het “oauth2/token” WSO2-eindpunt aanroepen zoals hieronder, waarbij de {{AUTHORIZATION_CODE}} de code is die ontvangen wordt door de callback URL:
curl --location --request POST 'https://localhost:9443/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id={{CLIENT_ID}}' \
--data-urlencode 'client_secret={{CLIENT_SECRET}}' \
--data-urlencode 'code={{AUTHORIZATION_CODE}}' \
--data-urlencode 'redirect_uri={{redirect_uri}}' \
--data-urlencode 'code_verifier={{code_verifier}}' \
Potentiële libraries om te gebruiken:
Als de application gebaseerd is op Angular, dan kan de “angular-oauth2-oidc” library gebruikt worden om de login flow van je applicatie te regelen: https://github.com/manfredsteyer/angular-oauth2-oidc. het is gecertificeerd en wordt aangeraden door de OpenID foundation die de OAUTH2 protocollen beheert.
Een referentie applicatie die met een lokale WSO2 Identity Server verbindt, vindt je hier: https://github.com/davebaol/oidc-angular-wso2is
Native Mobile Apps
De belangrijkste verschillen van de nieuwe login flow in vergelijking met de Password Grant flow staan hieronder beschreven.
In de Password Grant flow verzameld de Native App de inloggegevens van de gebruiker. In de nieuwe flow moet de app:
- een “code_verifier” genereren volgens https://tools.ietf.org/html/rfc7636#section-4.1 en deze onthouden (als het deze nog niet heeft)
- de code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) berekenen
- de “oauth2/authorize” url in de mobiele browser openen, inclusief de query parameters op een vergelijkbare manier met de web flow (response_type, scope, redirect_uri, client_id, nonce, code_challenge, code_challenge_method). Het is hier best practice om te vertrouwen op een mobiele browser om het inloggen af te handelen en geen webview in de app te gebruiken
- wanneer de gebruiker zijn inloggegevens in the browser invoert, en WSO2 de browser doorverwijst naar “redirect_uri”, zal de app naar deze url moeten luisteren en
- de “code” query parameter moeten uitlezen
- de code tegen een token moeten inwisselen, en daarbij ook de opgeslagen “code_verifier” (hetzelfde als Step 3 in de flow voor web-based applicaties)
Conclusie
We leven nu in een tijd waarin het Identity and Access Management landschap doorlopend verandert en uitgebreid wordt voor een vergroot aanpassingsvermogen, verbeterde connectiviteit via verschillende sociale media en zakelijke tools, terwijl daarbij de veiligheid van de gebruiker in de kern beschermd moet blijven. En ik geloof dat de OAUTH2 specificatie, aangevuld met een PKCE-verificatie een grote stap in goede richting is wat betreft onze capaciteit om verbindingen met verschillende systemen te leggen en creatieve authenticatie oplossingen te bieden aan eindgebruikers. Ik hoop dat dit artikel jou en jouw organisatie aan zal zetten om systemen hack-proof te maken en het daarbij een mooie balans met gebruikerservaring kan behouden.