Aurum Europe OAuth2 Authentication and Authorization Usage
Author: Twan van der Schoot (TvdS)
Date: 20170524
Version: 1.2
Status: final
Version History
Change History
| Date | Version | Changes | Author |
|---|---|---|---|
| 20170524 | 1.0 | Creation | TvdS |
| 20171010 | 1.1 | Verduidelijking van autorisatie flows, error respons toegevoegd, gebruik van access tokens toegevoegd, tokens intrekken toegevoegd | BB |
| 20180322 | 1.2 | Versimpeling uitleg. Authorisation Code Flow toegevoegd. | BB |
| 20200210 | 1.3 | Versimpeling uitleg. Revoke flow gecorrigeerd. | BB |
Inleiding
In dit document worden de door Aurum ondersteunde OAuth2 flows uitgelegd. Om een zo breed mogelijke acceptatie te garanderen hebben we ons heel strikt aan de RFCs gehouden.
Relevante RFCs
Met "de standaard" refereren we hier aan de relevante RFCs van de IETF taskforce:
- RFC6749 – The OAuth 2.0 Authorization Framework
- RFC6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage
- RFC6819 - OAuth 2.0 Threat Model and Security Considerations
- RFC7009 - OAuth 2.0 Token Revocation
Encoding
De vereiste encoding van het autorisatie verzoek is: application/x-www-form-urlencoded.
Scope
De RFC laat de invulling van de scope over aan de ontwikkelaars. In dit hoofdstuk leggen we onze invulling uit.
Een voorbeeld van een valide scope bij Aurum is realm:aurum role:organisation.
Realm
In de terminologie van RFC2617 §1.2 p.4:
These realms allow the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme and/or authorization database.
aurum: Inloggen gaat via de Aurum server.cep : Inloggen gaat via de Consumentenbond
Role
Met de role geef je aan voor welke rechten je toegang vraagt.
enduser: Een EnergyFlip gebruiker van de huidige Customer Profile en Customer Measurement APIs.organisation: Een Organisatie / EnergyGrip gebruiker.admin: Een Aurum Employee met administratieve rechten.partner: Een Aurum production partner.device: Gereserveerd voor devices.orderer: Gereserveerd voor de rol van een orderer in het fulfilment protocol.
Ondersteunde OAuth2 flows
In de OAuth2 RFC is er sprake van verschillende flows, elk met een eigen use case. Wij ondersteunen de volgende flows:
grant_type=authorization_code- RFC6749 §4.1 Authorization Code Grant. Bedoelt om als derde partij toegang te krijgen tot de gegevens van een eindgebruiker.grant_type=password- RFC6749 §4.3 Resource Owner Password Credentials Grant. Bedoelt om eindgebruikers direct toegang tot hun eigen data te geven. Het is niet de bedoeling dat derden deze flow gaan gebruiken omdat gebruikers dan direct hun credentials bij een derde partij moeten invoeren.grant_type=refresh_token- RFC6749 §6 Refreshing an Access Token. Bedoelt om de toegang tot de gegevens van een eindgebruiker te verlengen.
Authenticatie en autorisatie verzoek
Voor het verkrijgen van een access_token dient een verzoek te worden gedaan naar POST /oauth2/v1/token in het formaat x-www-form-urlencoded.
De client dient zich hierbij te authenticeren met zijn client_id en eventueel client_secret.
Dit kan volgens HTTP Basic met een Authorization: Basic header gevolgd door de tekst client_id:client_secret geëncodeerd in Base64.
Het mag ook meegegeven worden in de request body. Bijvoorbeeld: ...&client_id=abc&client_secret=123.
Als de client geen client_secret heeft gekregen mag deze worden weggelaten.
Het antwoord zal een bearer access token bevatten dat voldoet aan RFC6750 – The OAuth 2.0 Authorization Framework: Bearer Token Usage.
De access token heeft een relatief korte geldigheidsduur. Daarom wordt er ook een refresh_token meegegeven waarmee een nieuwe bearer access token kan worden opgevraagd.
Van het in de voorbeelden getoonde token formaat kan afgeweken worden.
Authorisation code verzoek
Met deze flow kan een derde partij op een veilige manier toegang krijgen tot de gegevens van een eindgebruiker. De eindgebruiker logt in op de website van Aurum en geeft daarna toestemming. De website stuurt dan een code door aan de client, via de redirect_uri, waarmee de client een autorisatie verzoek kan doen.
Verkrijgen van een code
De client stuurt de eindgebruiker door naar https://mijnaurum.nl/authorization/.
Als query parameters dienen meegegeven te worden:
client_idDeze heeft de client vooraf gekregen.redirect_uriDeze heeft de client zelf gedefinieerd bij de client registratie.response_typeMet als waardecode.
Optioneel mag ook een veld state meegegeven worden met een door de client in te vullen waarde. Deze waarde zal dan met de redirect meegestuurd worden.
Voorbeeld:
GET /authorization/?response_type=code&client_id=test123&redirect_uri=https:%2F%2Fmijnaurum.nl%2Fauthorization%2Fcallback&state=someState HTTP/1.1
Host: mijnaurum.nl
De eindgebruiker dient dan in te loggen en toegang te geven aan de client.
Als dat goed gaat zal er een redirect plaatsvinden naar de redirect_uri met als query parameter de code waarmee een autorisatie verzoek kan worden gedaan. Als het veld state is opgegeven zal deze hier ook aanwezig zijn.
Success voorbeeld:
GET /callback?code=63065f61-786f-4d12-9924-411709eb60e9&state=someState HTTP/1.1
Host: mijnaurum.nl
Als de gebruiker inlogt maar geen toestemming wil geven, zal ook een redirect plaatsvinden met een error respons. Error voorbeeld:
GET /callback?error=access_denied&state=someState HTTP/1.1
Host: mijnaurum.nl
Als de opgegeven redirect_uri niet geverifieerd kan worden, vind er geen redirect plaats.
Verkrijgen van autorisatie
Met de via de redirect verkregen code kan nu een autorisatie verzoek worden gedaan. De body van dit verzoek bevat de volgende verplichte velden:
grant_typemet als waardeauthorization_code.redirect_urimoet gelijk zijn aan wat er is gebruikt om de code op te vragen.codebevat de eerder verkregen code.
Voorbeeld verzoek:
POST /oauth2/v1/token HTTP/1.1
Host: api.aurumeurope.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=63065f61-786f-4d12-9924-411709eb60e9&redirect_uri=https:%2F%2Fmijnaurum.nl%2Fauthorization%2Fcallback&client_id=myClient&client_secret=mySecret
Password verzoek
Met dit verzoek kan een eindgebruiker direct toegang krijgen d.m.v. een gebruikersnaam en wachtwoord. De body van dit verzoek bevat de volgende verplichte velden:
grant_typemet als waardepassword.usernameis de identificatie van de eindgebruiker die inlogt. Bijrealm:aurumis dit het email adres.passwordis het wachtwoord van de eindgebruiker.scopemoet precies éénrealmen éénrolebevatten. Bijv:realm:aurum role:organisation.client_iddeze heeft de client vooraf gekregen.
Voorbeeld verzoek
POST /oauth2/v1/token HTTP/1.1
Host: api.aurumeurope.com
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=test@aurumeurope.com&password=verysecurepassword&scope=realm%3Caurum+role%3Corganisation&client_id=myClient&client_secret=mySecret
Refresh token verzoek
Met dit verzoek kan een toegang worden verlengd d.m.v. een refresh token. De body van dit verzoek bevat de volgende verplichte velden:
grant_typemet als waarderefresh_token.refresh_tokenbevat de refresh token van een eerder autorisatie verzoek.client_iddeze heeft de client vooraf gekregen.client_secretenkel als deze is gebruikt bij het ophalen van de token.
Let op:
Een refresh_token kan maar eenmalig gebruikt worden.
Bij gebruik zal een nieuwe refresh_token worden geleverd.
Om te voorkomen dat toegang onbedoeld verloren gaat bij een eventuele netwerk fout,
hebben wij een grace period van 5 minuten toegevoegd waarin de token opnieuw gebruikt kan worden.
Voorbeeld verzoek
POST /oauth2/v1/token HTTP/1.1
Host: api.aurumeurope.com
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=0db68343-e052-46f5-aa06-86fd7b2f4cdb&client_id=myClient&client_secret=mySecret
Success respons
Het antwoord op een autorisatie verzoek bevat de volgende verplichte velden in JSON formaat:
access_tokenis een bearer access token dat voldoet aan RFC6750 – The OAuth 2.0 Authorization Framework: Bearer Token Usageexpires_inis de tijd in seconden dat een access token geldig is.scopebevat de uiteindelijke scope van de toegewezen access token.refresh_tokenis een token met een lange geldigheidsduur dat gebruikt kan worden om een nieuwe access token op te vragen.token_typeis het type van de token. Bij ons zal dit vooralsnog altijdBearerzijn.
Een voorbeeld van het antwoord op een authenticatie / autorisatie verzoek ziet er als volgt uit:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store, no-cache
Pragma: no-cache
{
"access_token": "3dd920ec-fa86-41de-81ae-d37f293debb4",
"expires_in": 86399,
"scope": "realm:aurum role:organisation",
"refresh_token": "0db68343-e052-46f5-aa06-86fd7b2f4cdb",
"token_type": "Bearer",
}
Error respons
De error respons is in het standaard formaat zoals gedefinieerd in de OAuth2 specificaties. Zie hiervoor: §5.2 Error response en §3.1 Error Codes.
Een voorbeeld error respons ziet er als volgt uit:
{
"error": "invalid_grant"
}
De RFC staat toe zelf error codes te definiëren. Momenteel maken wij hier (nog) geen gebruik van.
Gebruik van een access token
Om de API's te gebruiken moet de access_token worden meegegeven middels een Authorization: Bearer header gevolgd door de access_token.
Deze standaard is beschreven in: §2.1 Authorization Request Header Field
Voorbeeld
Authorization: Bearer 3dd920ec-fa86-41de-81ae-d37f293debb4
Het intrekken van tokens
Als een gebruiker wil uitloggen dienen de verkregen tokens ongeldig gemaakt te worden. Het verwijderen van individuele tokens voldoet aan RFC7009 – OAuth 2.0 Token Revocation. Wij ondersteunen ook het verwijderen van alle tokens van de gebruiker. Hiervoor is geen RFC gedefinieerd.
Voor deze verzoeken dient de applicatie zich te authenticeren met zijn client credentials conform §2.3 Client Authentication.
Individuele tokens intrekken
Het verzoek voor het intrekken van individuele tokens is een POST naar /oauth2/v1/revoke waarbij de body in het formaat x-www-form-urlencoded is.
De body van dit verzoek bevat de volgende verplichte velden:
tokeneen access token of een refresh token. De server zoekt zelf uit welk type token het is.
De specificatie definieert ook een optioneel veld token_type_hint dat de server mag negeren. In onze implementatie wordt dit veld genegeerd. Er is dus geen voordeel aan het meesturen van dit veld.
Voorbeeld
POST /oauth2/v1/revoke HTTP/1.1
Host: api.aurumeurope.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=
token=0db68343-e052-46f5-aa06-86fd7b2f4cdb
In plaats van de Authorization header mogen de client credentials ook in de body worden geplaatst.
Voorbeeld: ...&client_id=abc&client_secret=123
Alle tokens intrekken
Het verzoek voor het intrekken van alle tokens is een POST naar /oauth2/v1/revokeAll zonder body.
Voorbeeld
POST /oauth2/v1/revokeAll HTTP/1.1
Host: api.aurumeurope.com
Authorization: Bearer 3dd920ec-fa86-41de-81ae-d37f293debb4
Antwoord
De server zal voor beide verzoeken altijd antwoorden met HTTP status code 200, tenzij de client/bearer authentication niet klopt. §2.2 Revocation Response beschrijft hierover:
Note: invalid tokens do not cause an error response since the client cannot handle such an error in a reasonable way. Moreover, the purpose of the revocation request, invalidating the particular token, is already achieved.