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

  • 297