oauth2 et openid connect
TRANSCRIPT
Agenda
● OIDC concepts● OIDC flows● Using OIDC with refresh token● OIDC OpenAM use case example
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
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é.
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
● 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
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 .
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)
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)
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
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é.
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
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" : "/"
}
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.
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.
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"
}
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 }
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.
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.
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
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
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}
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}
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
}
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}
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
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