27
Oauth2 & OpenID Connect Olivier Rivat [email protected] 23 Novembre 2016

Oauth2 et OpenID Connect

Embed Size (px)

Citation preview

Page 1: Oauth2 et OpenID Connect

Oauth2 & OpenID Connect

Olivier [email protected]

23 Novembre 2016

Page 2: Oauth2 et OpenID Connect

Agenda

● OIDC concepts● OIDC flows● Using OIDC with refresh token● OIDC OpenAM use case example

Page 3: Oauth2 et OpenID Connect

OpenID connect

● OIDC est défini a l'URL :– http://openid.net/specs/openid-connect-core-1_0.html

● OpenID connect est Oauth2 + Authentification :– OpenID Connect 1.0 est un simple layer d'identité construit au dessus

de oauth2.

– Il permet a des clients de vérifier leur identité auprès d'un serveur d'autorisation, et d'obtenir des informations sur l'utilisateur d'une façon JSON/REST-like.

– Oauth2 fournit un access token

– OIDC fournit un ID token

Page 4: Oauth2 et OpenID Connect

Role d'un access token ou d'un ID token

● Access Token :– Le rôle d'un access token peux être comparé a celui d'un billet de banque :

● On a besoin de savoir si le billet de banque est valide pour effectuer une transaction, mais le billet de banque « n'a pas de propriétaire attitré)

● L'access token est valide que pour une période prédéterminée

● ID_Token :

– Le rôle de l'id_token est similaire à celui d'une carte d'identité. L'ID token permet de prouver l'identité de l'utilisateur grâce a la signature, mais est seulement valable pour une période donné.

Page 5: Oauth2 et OpenID Connect

OpenID connect

● Les rôles définis dans OpenID connect sont :– End-User (OAuth 2.0 resource owner), dont les informations sont

accedees par l'application.

– Relying Party (RP) (OAuth 2.0 client) qui accède aux données protégées de l'utilisateur.

– OpenID Provider (OP) (OAuth 2.0 authorization server and also resource server) qui contient les données de l'utilisateur, et permet les accès

Page 6: Oauth2 et OpenID Connect

● Le protocole OpenID Connect suit les étapes suivantes

– Le RP (Cllient) envoie une requête au OpenID provider (OP)

– Le OP authentifie le end-user et obtient une autorisation

– Le OP répond avec un ID token, et éventuellement un access token

– Le RP peux faire des requêtes avec l'access token auprès du userinfo endpoint

– Le userInfo endpoint retourne des claims au sujet du end-user

Page 7: Oauth2 et OpenID Connect

Flow OpenID Connect (1)

● OpenID Connect fournit 3 type de flows :– Authorization Code flow

– Implicit Flow

– Hybrid Flow

Le type de flow a utiliser va être déterminé par le paramètre de requête response_type .

Page 8: Oauth2 et OpenID Connect

Flow OpenID Connect (2)● Authorization Code Flow

– Designed pour les applications utilisant oauth2 autorisation grant type

● Implicit Flow– Designed pour les RP (Relying Party) qui utilisent oauth2 en mode implicite.

– Ne permet pas la délivrance de refresh token.

● Hybrid Flow– Permet la delivrance d'Id Token, acces token et refresh token pour les besoins

EDF.

– Approche validé avec forgerock dans le ticket #16900: Using OIDC with Refresh token - access tokens and ID token generated using authoriwation code (Foregrock utilise openAM 14 en cours de développement)

Page 9: Oauth2 et OpenID Connect

OpenID Connect Concepts (1)

response_type" value Flow

code Authorization Code Flow

id_token Implicit Flow

id_token token Implicit Flow

code id_token Hybrid Flow

code token Hybrid Flow

code id_token token Hybrid Flow

● Le flow utilisé est déterminé par la valeur response_type contenu dans la requete de demande.

● (cf http://openid.net/specs/openid-connect-core-1_0.html#Authentication)

Page 10: Oauth2 et OpenID Connect

Lifecycle de OIDC avec OpenAM pour utiliser des refresh token (1)

Prérequis :● OpenAM est configuré en tant que Oauth2/OIDC provider

● Clients– Le client est enregistré auprès de L'oauth2/OIDC provider avec

clientID (nom du client), client secret (password de l'application)

– le refresh token a une durée de vie de 1 an

– L’autorisation code a une durée de vie courte (30s à une minute)

– L'access token et refresh token et id_token ont une durée de vie courte

● L'ID token a une durée de vie de 1heure chez google par exemple.● L'access token/refresh token ont une durée de vie courte (quelques

minutes).

– Tous ces paramètres sont configurables

Page 11: Oauth2 et OpenID Connect

Lifecycle de OIDC avec OpenAM pour utiliser des refresh token (2)

● Resfresh Token

– Le Refresh token est unique pour un utilisateur donné

– Il permet de regénérer un access token/id_token en utilisant une requete de type grant_type=refresh_token.

– Il est possible de révoquer un refresh token d'un utilisateur donné.

Page 12: Oauth2 et OpenID Connect

Lifecycle de OIDC avec OpenAM pour utiliser des refresh token (3)

● Step1: (demande d’autorisation code)

– Requête:L'utilisateur va effectuer un requête de type « code id_token token »

– Réponse : l'utilisateur reçoit un réponse avec code autorisation, access token et de_token.

● Step2 (utilisation de l'autorisation code)– Requête : L'utilisateur utilise l'autorisation code

– Réponse : l'utilisateur reçoit un access, refresh token, id_token clientID (nom du client), client secret (password de l'application)

● Utilisation du refresh Token (au cours de l'année)

– Requête : Utilisation du refresh token – Génération d'un nouvel access token /id token

Page 13: Oauth2 et OpenID Connect

Lecture Access token● curl http://openam.example.com:18080/openam/oauth2/tokeninfo?

access_token=295768a3-6303-47a0-b31a-5ab82d4f27be | json_pp

{"openid" : "", "expires_in" : 8312, "access_token" : "295768a3-6303-47a0-b31a-5ab82d4f27be", "token_type" : "Bearer","grant_type" : "token","profile" : "","scope" : ["openid","profile"],"realm" : "/"

}

Page 14: Oauth2 et OpenID Connect

ID_Token (1)

● ID Token :– L'ID token se decompose en 3 parties :

● header● payload● Signature

– Le header et la payload sont encodes en base 64, et peuvent etre faciment lus en decodeant leur format en base 64.

– La signature est un hash des composants suivants: header, payload, secret.

– Le secret est la signauture du serveur, qui permet de verifier des tokens et d'en signer des nouveaux.

Page 15: Oauth2 et OpenID Connect

ID_Token(2)● Verification d'un ID Token :

– La verification d'un ID token contient environ une dizaine de points dont certains optionels.

– Est definit dans la spec openID Connect (3.1.3.7. ID Token Validation, http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken)

– Certains points sont quasiment immediat a verifier (sujet, audience, validite, expiration …)

– D'autre points sont complexes (verfication de la signature, necessitant l'usage de libraies JWT pour verifier le token)

● Verification d'un access Token– De meme, il est possible de valider un access token, en utilisant le

champ at_hash de l'id_token et en calculant un hash a partir de l'access token.

Page 16: Oauth2 et OpenID Connect

ID_Token(3) de l'id_token (partie 1, header)

● echo -n"eyAidHlwIjogIkpXVCIsICE6yS51mL28Knwvt44....." > id_token_file.txt

cat id_token_file.txt | cut -d "." -f 1 | base64 -d

{ "typ": "JWT", "kid": "SylLC6Njt1KGQktD9Mt+0zceQSU=", "cty": "JWT", "alg": "RS256"

}

Page 17: Oauth2 et OpenID Connect

ID_token(4) l'id_token (partie 2, payload)

● cat id_token_file.txt | cut -d "." -f 2 | base64 -d

{ "at_hash": "LeIYnGnGzC0LyyFMZNuKhA", "sub": "demo", "iss": "http://openam.example.com:18080/openam/oauth2", "tokenName": "id_token", "aud": [ "myClientID" ], "ops": "d0b5bb52-ac6a-464e-be02-a6723f4ebed6", "azp": "myClientID", "auth_time": 1467842810, "realm": "/", "exp": 1467843410, "tokenType": "JWTToken", "iat": 1467842810 }

Page 18: Oauth2 et OpenID Connect

Analyse d'un ID_Token (1)

● Un id_token issu de OPENAM est composé de claims.

● Les claims obligatoires sont :– iss: Issuer Identifier for the Issuer of the response.

– sub: Subject Identifier. A locally unique and never reassigned identifier within the Issuer for the End-User

– aud: Audience(s) that this ID Token is intended for. It MUST contain the OAuth 2.0 client_id of the Relying Party as an audience value

– exp: Expiration time on or after which the ID Token MUST NOT be accepted for processing.

– iat: Time at which the JWT was issued. Its value is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the

date/time.

Page 19: Oauth2 et OpenID Connect

Analyse d'un ID_Token (2)

● Les claims optionnelles sont :– auth_time: Time when the End-User authentication occurred.

– nonce: String value used to associate a Client session with an ID Token, and to mitigate replay attacks.

– azp : Authorized party - the party to which the ID Token was issued. If present, it MUST contain the OAuth 2.0 Client ID of this party.

– at_hash:Access Token hash value. Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the access_token value, where the hash algorithm used is the hash algorithm used in the alg Header Parameter of the ID Token's Header.

Page 20: Oauth2 et OpenID Connect

Remontée d'information OpenID

● Il existe 2 mécanismes avec openID pour remonter des informations :– Utilisation des scope dans les access access token

– Utilisation de claims

● OpenID fourni des claims standard (i.e par défaut), et il est possible de customiser cette liste avec des attributs spécifiques– Le mécanisme de customisation des claims fonctionne pas ou mal avec

openam12 (http://www.janua.fr/openid-connect-with-openam/)

– On doit utiliser la feature scope des access tokens pour remonter des infos depuis le LDAP

Page 21: Oauth2 et OpenID Connect

OIDC example ( part 1) - (Obtention de l'autorisation code)

curl -i --cookie "iplanetDirectoryPro=$1" \http://openam.example.com:18080/openam/oauth2/authorize \--data "realm=%2f&\scope=openid%20profile%20mail%20employeenumber&\response_type=code%20id_token%20token&\client_id=myClientID&\redirect_uri=http://openam.example.com:18080/openid/cb-basic.html&\decision=Allow"

● HTTP/1.1 302 FoundCache-Control: no-storeDate: Fri, 18 Nov 2016 14:25:21 GMTAccept-Ranges: bytesLocation: http://openam.example.com:18080/openid/cb-basic.html#access_token=640f8fe9-b2f2-43f8-b2cc-72d525d47926&code=83ecdf77-6bbd-4e0d-9fe0-c0ada4fb4a68&scope=employeenumber%20mail%20openid%20profile&id_token=eyAidHlwIjogIkpXVCIsICJraWQiOiAiU3lsTEM2Tmp0MUtHUWt0RDlNdCswemNlUVNVPSIsICJjdHkiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIgfQ.eyAiYXRfaGFzaCI6ICJZVFphQnRvRWM3bi1HYnVrWnZfZ0tnIiwgInN1YiI6ICJkZW1vIiwgImlzcyI6ICJodHRwOi8vb3BlbmFtLmV4YW1wbGUuY29tOjE4MDgwL29wZW5hbS9vYXV0aDIiLCAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF1ZCI6IFsgIm15Q2xpZW50SUQiIF0sICJjX2hhc2giOiAiZlV5Sl9nRVRFVXA5OExwX0MtNkRMZyIsICJvcHMiOiAiNzY1ZDQxMjktMTU3Ny00MjUyLWE0NTktNTQ4NDBjODNiOTBjIiwgImF6cCI6ICJteUNsaWVudElEIiwgImF1dGhfdGltZSI6IDE0Nzk0NzkxMjEsICJyZWFsbSI6ICIvIiwgImV4cCI6IDE0Nzk0ODI3MjEsICJ0b2tlblR5cGUiOiAiSldUVG9rZW4iLCAiaWF0IjogMTQ3OTQ3OTEyMSB9.i9_amp9bNvB2PS4dUp7tdY4M_StryIpuo6fsJm3Rhql3nLjdN2eGUzdLowG2g5qwh4gKbR4fYaK-vodqBJEbO0wvW2YOhg6enLCJnJFm8w5DCfzfKNfoVo-nr5Y4Bc2RD_8K16JdcX2hvbO42NSb9gFuiJ2Qs6-rtON7pEEUfFk&token_type=Bearer&expires_in=3599

Page 22: Oauth2 et OpenID Connect

OIDC example ( part 2) - (Utilisation de l'autorisation code)

"curl -i http://openam.example.com:18080/openam/oauth2/access_token \ --data realm=%2f&grant_type=authorization_code \&code=83ecdf77-6bbd-4e0d-9fe0-c0ada4fb4a68 \&client_id=myClientID \&redirect_uri=http://openam.example.com:18080/openid/cb-basic.html&decision=Allow

HTTP/1.1 200 OKCache-Control: no-store Date: Fri, 18 Nov 2016 14:26:22 GMTAccept-Ranges: bytes Server: Restlet-Framework/2.1.7Vary: Accept-Charset, Accept-Encoding, Accept-Language, AcceptContent-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked

● {"access_token":"dff56614-131a-4e4d-930c-9df9945bfcbf","refresh_token":"9a187f2d-4715-4e58-b208-bd5b8d61e769","scope":"employeenumber mail openid profile","id_token":"eyAidHlwIjogIkpXVCIsICJraWQiOiAiU3lsTEM2Tmp0MUtHUWt0RDlNdCswemNlUVNVPSIsICJjdHkiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIgfQ.eyAiYXRfaGFzaCI6ICJVSHk5NHhiOFRWYmFQZnNxUW9Na3BBIiwgInN1YiI6ICJkZW1vIiwgImlzcyI6ICJodHRwOi8vb3BlbmFtLmV4YW1wbGUuY29tOjE4MDgwL29wZW5hbS9vYXV0aDIiLCAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF1ZCI6IFsgIm15Q2xpZW50SUQiIF0sICJjX2hhc2giOiAiZlV5Sl9nRVRFVXA5OExwX0MtNkRMZyIsICJvcHMiOiAiOTMyODJhNWQtODNlMi00NWJiLWEzMzEtYmU2Y2IzNGExYjgzIiwgImF6cCI6ICJteUNsaWVudElEIiwgImF1dGhfdGltZSI6IDE0Nzk0NzkxODIsICJyZWFsbSI6ICIvIiwgImV4cCI6IDE0Nzk0ODI3ODIsICJ0b2tlblR5cGUiOiAiSldUVG9rZW4iLCAiaWF0IjogMTQ3OTQ3OTE4MiB9.Pi4InA3lWDx6uxS0rEmTp-X2LRQaWTJ0gFp2OcN9_n7Dn2oJISZAPrcBkggyDxafcImJV3q0dzgeTlW6jyebSsV8RjMJGTMgBR-5WCn05KhTWJJouw-FQGZjByX3_IFqI4gghle4ePsaJxMKBKRtZd63HR5VcyLVCTkIGQEINS8","token_type":"Bearer","expires_in":3599}

Page 23: Oauth2 et OpenID Connect

OIDC example ( part 2) - (Utilisation de l'autorisation code)

"curl -i http://openam.example.com:18080/openam/oauth2/access_token \ --data realm=%2f&grant_type=authorization_code \&code=83ecdf77-6bbd-4e0d-9fe0-c0ada4fb4a68 \&client_id=myClientID \&redirect_uri=http://openam.example.com:18080/openid/cb-basic.html&decision=Allow

HTTP/1.1 200 OKCache-Control: no-store Date: Fri, 18 Nov 2016 14:26:22 GMTAccept-Ranges: bytes Server: Restlet-Framework/2.1.7Vary: Accept-Charset, Accept-Encoding, Accept-Language, AcceptContent-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked

● {"access_token":"dff56614-131a-4e4d-930c-9df9945bfcbf","refresh_token":"9a187f2d-4715-4e58-b208-bd5b8d61e769","scope":"employeenumber mail openid profile","id_token":"eyAidHlwIjogIkpXVCIsICJraWQiOiAiU3lsTEM2Tmp0MUtHUWt0RDlNdCswemNlUVNVPSIsICJjdHkiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIgfQ.eyAiYXRfaGFzaCI6ICJVSHk5NHhiOFRWYmFQZnNxUW9Na3BBIiwgInN1YiI6ICJkZW1vIiwgImlzcyI6ICJodHRwOi8vb3BlbmFtLmV4YW1wbGUuY29tOjE4MDgwL29wZW5hbS9vYXV0aDIiLCAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF1ZCI6IFsgIm15Q2xpZW50SUQiIF0sICJjX2hhc2giOiAiZlV5Sl9nRVRFVXA5OExwX0MtNkRMZyIsICJvcHMiOiAiOTMyODJhNWQtODNlMi00NWJiLWEzMzEtYmU2Y2IzNGExYjgzIiwgImF6cCI6ICJteUNsaWVudElEIiwgImF1dGhfdGltZSI6IDE0Nzk0NzkxODIsICJyZWFsbSI6ICIvIiwgImV4cCI6IDE0Nzk0ODI3ODIsICJ0b2tlblR5cGUiOiAiSldUVG9rZW4iLCAiaWF0IjogMTQ3OTQ3OTE4MiB9.Pi4InA3lWDx6uxS0rEmTp-X2LRQaWTJ0gFp2OcN9_n7Dn2oJISZAPrcBkggyDxafcImJV3q0dzgeTlW6jyebSsV8RjMJGTMgBR-5WCn05KhTWJJouw-FQGZjByX3_IFqI4gghle4ePsaJxMKBKRtZd63HR5VcyLVCTkIGQEINS8","token_type":"Bearer","expires_in":3599}

Page 24: Oauth2 et OpenID Connect

OIDC example ( part 3) - (lecture access token)

curl http://openam.example.com:18080/openam/oauth2/tokeninfo?access_token=dff56614-131a-4e4d-930c-9df9945bfcbf

{ "token_type" : "Bearer","access_token" : "dff56614-131a-4e4d-930c-9df9945bfcbf","grant_type" : "authorization_code","profile" : "","mail" : "[email protected]","openid" : "","realm" : "/","employeenumber" : "EDF1234567","scope" : ["employeenumber","mail","openid","profile"],

"expires_in" : 3520

}

Page 25: Oauth2 et OpenID Connect

OIDC example ( part 4) - (utilisation du refresh token)

+ curl -X POST http://openam.example.com:18080/openam/oauth2/access_token?scope=profile%20mail%20openid%20employeenumber -u myClientID:oauthclient -d grant_type=refresh_token -d refresh_token=9a187f2d-4715-4e58-b208-bd5b8d61e769

{"access_token":"8d588b5a-baa7-4df8-96f1-6b52272b7ca9","scope":"employeenumber mail openid profile","id_token":"eyAidHlwIjogIkpXVCIsICJraWQiOiAiU3lsTEM2Tmp0MUtHUWt0RDlNdCswemNlUVNVPSIsICJjdHkiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIgfQ.eyAiYXRfaGFzaCI6ICJfbGdGdEIzZW9YYmFMeVRKZ05LUlJRIiwgInN1YiI6ICJkZW1vIiwgImlzcyI6ICJodHRwOi8vb3BlbmFtLmV4YW1wbGUuY29tOjE4MDgwL29wZW5hbS9vYXV0aDIiLCAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF1ZCI6IFsgIm15Q2xpZW50SUQiIF0sICJvcHMiOiAiNmMyZWIwYjctYmMzMS00MjNhLWIyYTQtOTliNTVjZGNhYmQ5IiwgImF6cCI6ICJteUNsaWVudElEIiwgImF1dGhfdGltZSI6IDE0Nzk0NzkzMjQsICJyZWFsbSI6ICIvIiwgImV4cCI6IDE0Nzk0ODI5MjQsICJ0b2tlblR5cGUiOiAiSldUVG9rZW4iLCAiaWF0IjogMTQ3OTQ3OTMyNCB9.b9IjRpKn6S5_eByN4_Awu6sZslSOPHXRu8GRBNoaUoroXeAieNPTyozKEBuAa2Dwb2NShicThvzmg0PRxmnPFeNfN0S6A94y6K-u5bjErGxAJjia2Fdx4IicUb6bmXisgCh9aCkxfMCpEUspPqIlAp-FywGV4q53an-ewrn2x7E","token_type":"Bearer","expires_in":3599}

Page 26: Oauth2 et OpenID Connect

OpenAM et OpenID Connect● OpenAM permet de definir un OpenID/Oauth2

provider et de meme client Oauth2● Interfacage :

– Provider● Definir un Oauth2/OpenID Server provider (IDP openID) en utilisant

OpenAM● Definir les scopes necessaires

– Client:● Enregistrer un Oauth2 Client (mode implicite) aupres de l'IDP

openID connect dans l'openAM (possibel de facon dynamique)● Recuperer 2 jetons dans la reponse: id_token et access_token● Validations de l'id_token

Page 27: Oauth2 et OpenID Connect

OpenID Connect Concepts (2)● Dans le cas de mode implicite, les 2 tokens sont

renvoyés dans la reponse. Exemple :● curl -i --cookie "iplanetDirectoryPro=$1" \

http://openam.example.com:18080/openam/oauth2/authorize \--data "realm=%2f&scope=openid%20profile&\response_type=id_token%20token&\client_id=myClientID&\redirect_uri=http://openam.example.com:18080/openid/cb-implicit.html&\decision=Allow"

● Location: http://openam.example.com:18080/openid/cb-implicit.html#access_token=295768a3-6303-47a0-b31a-5ab82d4f27be&scope=openid%20profile&id_token=eyAidHlwIjogIkpXVCIsICJraWQiOiAiU3lsTEM2Tmp0MUtHUWt0RDlNdCswemNlUVNVPSIsICJjdHkiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIgfQ.eyAiYXRfaGFzaCI6ICJMZUlZbkduR3pDMEx5eUZNWk51S2hBIiwgInN1YiI6ICJkZW1vIiwgImlzcyI6ICJodHRwOi8vb3BlbmFtLmV4YW1wbGUuY29tOjE4MDgwL29wZW5hbS9vYXV0aDIiLCAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF1ZCI6IFsgIm15Q2xpZW50SUQiIF0sICJvcHMiOiAiZDBiNWJiNTItYWM2YS00NjRlLWJlMDItYTY3MjNmNGViZWQ2IiwgImF6cCI6ICJteUNsaWVudElEIiwgImF1dGhfdGltZSI6IDE0Njc4NDI4MTAsICJyZWFsbSI6ICIvIiwgImV4cCI6IDE0Njc4NDM0MTAsICJ0b2tlblR5cGUiOiAiSldUVG9rZW4iLCAiaWF0IjogMTQ2Nzg0MjgxMCB9.asSMNjQ29gqrXtLCkTigswFOhtAN-e8lfeU-nESmK0P09hA7OLhfpR10L1ta-f646i0i5728OVAqC7du0EP5Bmm9w1xL__JqMzCFXnHI-jYVGKGKVrGIVtIy9kS2Zj86E4zLTVsiy7egX-ZKXGZSTpNjD8E6yS51mL28Knwvt44&token_type=Bearer&expires_in=8399