Les bonnes pratiques


conjuguées au présent, passé simple et futur

Mathieu
Tech Lead @
Humbert
Dévelopeur Backend depuis 15 ans
Architecture - DevOps - Sécurité

@math7t



Mathieu

Tech Lead @

Humbert
Dévelopeur Backend depuis 15 ans
Architecture - DevOps - Sécurité

@math7t









Qui a déjà travaillé avec Oauth 2.0 / OpenId Connect ?
Qui a déjà travaillé avec Oauth 1 ?
?
Social Login
Single Sign-on
Authentification Fédérée

Le problème initial
Import des contacts

Le problème initial
Import des contacts







API



API




API


On veux obtenir l'autorisation d'accès aux contacts
via un Token d'API
Alternative
Un petit tutoriel
Alternative
Un petit tutoriel
1 - Va sur ton service Mail
2 - Authenfie toi si besoin, pas mon problème
3 - Va sur ta page profile, section "developer"
4 - Génère un token d'API, restreint sur la gestion des contacts
5 - Copie le token d'API
6 - Reviens chez moi et donne moi ce token, stp
Alternative
Un petit tutoriel
1 - Va sur ton service Mail
2 - Authenfie toi si besoin, pas mon problème
3 - Va sur ta page profile, section "developer"
4 - Génère un token d'API, restreint sur la gestion des contacts
5 - Copie le token d'API
6 - Reviens chez moi et donne moi ce token, stp
OAuth 2.0 décrit comment automatiser ce besoin
C'est un framework d'
autorisation
Comment ?

Je veux importer mes contacts


Redirect -> https://emails.com/authorize


Redirect -> https://emails.com/authorize
?
client_id=facebook
scope=contacts
redirect_uri=https://...
Token


Redirect -> https://emails.com/authorize
?
client_id=facebook
scope=contacts
redirect_uri=https://...
- Authentification
- Consentement
Token


Redirect -> https://emails.com/authorize
?
client_id=facebook
scope=contacts
redirect_uri=https://...
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?token=rkj2oirj23
Token

HARD

Redirect -> https://emails.com/authorize
?
client_id=facebook
scope=contacts
redirect_uri=https://...
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?token=rkj2oirj23
Token
IMPLICIT FLOW

Token
IMPLICIT FLOW
Resource Owner (RO)
API Contacts : Resource Server
Contacts : Resource
Client
Client
AS
Authorization Server (AS)

HARD

Redirect -> https://emails.com/authorize
?
client_id=facebook
scope=contacts
redirect_uri=https://...
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?token=rkj2oirj23
Token
IMPLICIT FLOW
SÉCURISÉ
?
?
BACK-CHANNEL


HTTPS
Client
Server
front-end
back-end
?
BACK-CHANNEL



HTTPS
Client
Server
front-end
back-end
FRONT-CHANNEL

HTTP Redirects
Server
Server

Browser
Tout passe par les URLs
?

FRONT-CHANNEL

HTTP Redirects
Server
Server

Browser
Tout passe par les URLs
Browser History
Browser Add-ons
HTTP Referer
Logs serveur
Redirect -> https://emails.com/authorize
?
client_id=facebook
scope=contacts
redirect_uri=https://...
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?token=rkj2oirj23
Token
Client
AS

Par quoi on le remplace ?
Simple
Par quoi on le remplace ?
Simple
Par un autre token !

Par quoi on le remplace ?
Simple
Par un autre token !
Ephémère
Utilisable qu'une fois
Ne sert qu'à récupérer le vrai token via une requète de back-channel
Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Client
AS

Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Client
AS

Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?code=rkj2oirj23
Client
AS

Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?code=rkj2oirj23
POST https://emails.com/token

Client
Client
AS
AS

Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?code=rkj2oirj23
POST https://emails.com/token

Token
Client
Client
AS
AS

Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?code=rkj2oirj23
POST https://emails.com/token

Token
Client
Client
AS
Authorization Code flow
AS

SÉCURISÉ
?
Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?code=rkj2oirj23
POST https://emails.com/token

Token
Client
Client
AS
1
2
AS

Redirect -> https://emails.com/authorize
- Authentification
- Consentement
Redirect -> https://facebook.com/callback?code=rkj2oirj23
POST https://emails.com/token

Token
Client
Client
AS
1
2
Comment authentifier le client ?
redirect_uri
client_id
client_secret

AS
Comment authentifier le client ?
client_secret

Mobile
SPA
Backend
PKCE
https://emails.com/authorize
https://emails.com/token

Client
Client
AS
code_verifier
Random string
code_challenge
Hash verifier

AS
https://emails.com/authorize
https://emails.com/token

Client
Client
AS
code_verifier
code_challenge
PKCE

AS
https://emails.com/authorize
https://emails.com/token

Client
Client
AS
code_verifier
code_challenge
PKCE

AS
https://emails.com/authorize
https://emails.com/token

Client
Client
AS
code_verifier
code_challenge
PKCE
+

AS
Authorization Code
PKCE
+

Mobile
SPA
Backend
Refresh flow
POST https://emails.com/token

Token
Client
AS
Refresh Token

Quelques trucs en +
Quelques trucs en +
Redirect URI
Redirect -> https://www.monclient.com/callback?code=rkj2oirj23
Client
redirect_uri

AS

AS

AS
Quelques trucs en +
Pre-registered Redirect URI
https://www.monclient.com/callback

AS
https:// *.monclient.com/callback
https://www.monclient.com/callback?*
https://www.monclient.com/callback
Direct match
Quelques trucs en +
Redirect URI
Redirect -> https://facebook.com/callback_as2?code=rkj2oirj23
Client

AS 2

AS 3

AS 1
Redirect -> https://facebook.com/callback_as3?code=rkj2oirj23
Redirect -> https://facebook.com/callback_as1?code=rkj2oirj23
Librairies standards recommendées par l'IETF





Autorisation
Authentification
access_token :
fj3984jrqjrqp8qoijr11
id_token :
JWT


Autorisation
Authentification
access_token :
fj3984jrqjrqp8qoijr11
id_token :
JWT

{
"sub": "1234567890",
"iat": 1516239022,
"exp": 1516239023,
"name": "John Doe"
}Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

{
"sub": "1234567890",
"iat": 1516239022,
"exp": 1516239023,
"name": "John Doe"
}Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature


{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}{
"alg": "HS256",
"typ": "JWT"
}Header
Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}{
"alg": "none",
"typ": "JWT"
}Header
Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}{
"alg": "none",
"typ": "JWT"
}Header
Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

Algorithm algorithm = Algorithm.HMAC256("secret");
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("mon-authorization-server")
.build();
DecodedJWT jwt = verifier.verify(token);

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}{
"alg": "none",
"typ": "JWT"
}Header
Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

Algorithm algorithm = Algorithm.RSA256(publicKey)
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("mon-authorization-server")
.build();
DecodedJWT jwt = verifier.verify(token);

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}{
"alg": "RSA256",
"typ": "JWT",
"kid": "27irj93yh2"
}Header
Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

Rotation des clés

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}{
"alg": "RSA256",
"typ": "JWT",
"kid": "27irj93yh2"
}Header
Payload
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)Signature

Rotation des clés
Pas de partout

Alternatives au


BISCUIT
par


Alternatives au


BISCUIT
par

Et le futur alors ?

Et le futur alors ?
Financial-Grade API (FAPI)
Grant Negociation and Authorization Protocol (GNAP)
Google's Zanzibar

Passwordless with WebAuthn
Merci !

@math7t
Oauth2 / OpenID Connect
By Mathieu HUMBERT
Oauth2 / OpenID Connect
- 368