Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Architecte technique chez
depuis 2011
+5 ans d’expérience sur une quinzaine de
projets Symfony2 de tous types
1
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
Edition Ajout Sup...
CRUCIAL de veiller à une
sécurité accrue de chaque API
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
 est normalement...
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
 est normalement...
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
 est normalement...
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
 est normalement...
 Authentification basée sur la session
Inconvénients
 CORS (Cross-origin resource sharing)
 Évolutivité
 Authentification basée sur les clefs d’API
Pas de session
 Authentification basée sur les clefs d’API
Pas de session
Gestion des clefs en bdd
1 andre … z654df84sSdDLfs3
2 amine … ...
 Authentification basée sur les clefs d’API
Pas de session
Gestion des clefs en bdd
Pas de mécanisme d’expiration
 Authentification basée sur les clefs d’API
Pas de session
Gestion des clefs en bdd
Pas de mécanisme d’expiration
Token n...
Solution idéale :
 Stateless
 Gestion de l’expiration
 Auto-porteuse et sécurisée
2
 Standard industriel qui repose sur une RFC (7519)
 Permet de fournir un mécanisme d’authentification fiable
 Repose su...
 Liste des propriétés réservées :
Nom: sub
Description: Subject
Nom: exp
Description: Expiration Time
Nom: nbf
Descriptio...
JOSE : Javascript Object Signing and Encryption
HMAC + SHA RSA + SHA ECDSA + SHA
 Implémentation disponible pour la grande majorité des langages
de développement
Etape 1 :
 L’utilisateur va s’authentifier sur l’API
 En cas d’authentification réussie, le serveur génère et
renvoie un...
Etape 2 à N :
 L’application transmet le token JWT pour chaque
transaction suivante en header des requêtes
Quelle durée choisir ?
 Pas de durée type
 En moyenne : entre 5 min et 1 heure
 Délai expiré :
Utilisation de Refresh token
3
namespace SymfonyComponentSecurityGuard;
abstract class AbstractGuardAuthenticator
{
public function createAuthenticatedTo...
namespace SymfonyComponentSecurityGuard;
abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface
...
namespace SymfonyComponentSecurityGuard;
interface GuardAuthenticatorInterface
{
public function getCredentials(Request $r...
namespace SymfonyComponentSecurityGuard;
interface GuardAuthenticatorInterface extends AuthenticationEntryPointInterface
{...
namespace SymfonyComponentSecurityHttpEntryPoint;
interface AuthenticationEntryPointInterface
{
public function start(Requ...
#app/config/security.yml
security:
encoders:
SymfonyComponentSecurityCoreUserUserInterface: plaintext
providers:
in_memory...
#app/config/security.yml
security:
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: in_mem...
# app/config/service.yml
services:
webnet_authentication.handler.authentication_success:
class: AppBundleSecurityAuthentic...
/**
* Class AuthenticationFailureHandler
*
* @package AppBundleSecurity
*/
class AuthenticationFailureHandler implements A...
/**
* Class AuthenticationSuccessHandler
*
* @package AppBundleSecurity
*/
class AuthenticationSuccessHandler implements A...
/**
* Class AuthenticationSuccessHandler
* @package AppBundleSecurity
*/
class AuthenticationSuccessHandler implements Aut...
# app/config/services.yml
services:
app.token_authenticator:
class: AppBundleSecurityWebnetTokenAuthenticator
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthentic...
« There’s a bundle for that ! »
o lexik/LexikJWTAuthenticationBundle
o gesdinet/JWTRefreshTokenBundle (refresh token)

JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
Vous avez terminé ce document.
Télécharger et lire hors ligne.
Prochain SlideShare
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Suivant
Prochain SlideShare
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Suivant
Télécharger pour lire hors ligne et voir en mode plein écran

Partager

JWT - Sécurisez vos APIs

Télécharger pour lire hors ligne

Les web-services sont aujourd'hui au centre des SI de nos entreprises. Ils permettent de transmettre l'information entre des systèmes hétérogènes, à la fois au sein de l’entreprise mais également à l'extérieur, notamment et de plus en plus vers des systèmes mobiles. Or exposer cette information, potentiellement critique, pose la question de la sécurisation de ces échanges. Cette présentation sera l'occasion de présenter JWT, d'expliquer son fonctionnement et son implémentation au sein d'un projet Symfony 3.

Livres associés

Gratuit avec un essai de 30 jours de Scribd

Tout voir
  • Soyez le premier à aimer ceci

JWT - Sécurisez vos APIs

  1. 1. Architecte technique chez depuis 2011 +5 ans d’expérience sur une quinzaine de projets Symfony2 de tous types
  2. 2. 1
  3. 3. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information
  4. 4. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information Edition Ajout Suppression
  5. 5. CRUCIAL de veiller à une sécurité accrue de chaque API
  6. 6. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  Pas de session  Appel isolé
  7. 7. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  Pas de session  Appel isolé
  8. 8. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  Pas de session  Appel isolé  Authentification à chaque appel
  9. 9. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  doit être utilisée en HTTPS
  10. 10.  Authentification basée sur la session
  11. 11. Inconvénients  CORS (Cross-origin resource sharing)  Évolutivité
  12. 12.  Authentification basée sur les clefs d’API Pas de session
  13. 13.  Authentification basée sur les clefs d’API Pas de session Gestion des clefs en bdd 1 andre … z654df84sSdDLfs3 2 amine … Ohg2v5x6df2fFspoa1fdffds8 3 antoine … khHp5se8w2xf1t9823tz3
  14. 14.  Authentification basée sur les clefs d’API Pas de session Gestion des clefs en bdd Pas de mécanisme d’expiration
  15. 15.  Authentification basée sur les clefs d’API Pas de session Gestion des clefs en bdd Pas de mécanisme d’expiration Token non exploitable
  16. 16. Solution idéale :  Stateless  Gestion de l’expiration  Auto-porteuse et sécurisée
  17. 17. 2
  18. 18.  Standard industriel qui repose sur une RFC (7519)  Permet de fournir un mécanisme d’authentification fiable  Repose sur un token qui va contenir les données  Token sécurisé o JWS (RFC 7515) o JWE (RFC 7516)  Fournit un système d’expiration
  19. 19.  Liste des propriétés réservées : Nom: sub Description: Subject Nom: exp Description: Expiration Time Nom: nbf Description: Not Before Nom: aud Description: Audience Nom: iss Description: Issuer Nom: iat Description: Issued At Nom: jti Description: JWT ID
  20. 20. JOSE : Javascript Object Signing and Encryption HMAC + SHA RSA + SHA ECDSA + SHA
  21. 21.  Implémentation disponible pour la grande majorité des langages de développement
  22. 22. Etape 1 :  L’utilisateur va s’authentifier sur l’API  En cas d’authentification réussie, le serveur génère et renvoie un token JWT à l’application
  23. 23. Etape 2 à N :  L’application transmet le token JWT pour chaque transaction suivante en header des requêtes
  24. 24. Quelle durée choisir ?  Pas de durée type  En moyenne : entre 5 min et 1 heure  Délai expiré :
  25. 25. Utilisation de Refresh token
  26. 26. 3
  27. 27. namespace SymfonyComponentSecurityGuard; abstract class AbstractGuardAuthenticator { public function createAuthenticatedToken(UserInterface $user, $providerKey); }
  28. 28. namespace SymfonyComponentSecurityGuard; abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface { public function createAuthenticatedToken(UserInterface $user, $providerKey); }
  29. 29. namespace SymfonyComponentSecurityGuard; interface GuardAuthenticatorInterface { public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function supportsRememberMe(); }
  30. 30. namespace SymfonyComponentSecurityGuard; interface GuardAuthenticatorInterface extends AuthenticationEntryPointInterface { public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function supportsRememberMe(); }
  31. 31. namespace SymfonyComponentSecurityHttpEntryPoint; interface AuthenticationEntryPointInterface { public function start(Request $request, AuthenticationException $authException = null); }
  32. 32. #app/config/security.yml security: encoders: SymfonyComponentSecurityCoreUserUserInterface: plaintext providers: in_memory: memory: users: andre: password: I_<3_Webnet roles: ROLE_ADMIN
  33. 33. #app/config/security.yml security: firewalls: login: pattern: ^/api/login stateless: true anonymous: true provider: in_memory form_login: check_path: /api/login_check success_handler: webnet_authentication.handler.authentication_success failure_handler: webnet_authentication.handler.authentication_failure require_previous_session: false use_referer: true access_control: - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  34. 34. # app/config/service.yml services: webnet_authentication.handler.authentication_success: class: AppBundleSecurityAuthenticationSuccessHandler arguments: [] webnet_authentication.handler.authentication_failure: class: AppBundleSecurityAuthenticationFailureHandler arguments: []
  35. 35. /** * Class AuthenticationFailureHandler * * @package AppBundleSecurity */ class AuthenticationFailureHandler implements AuthenticationFailureHandlerInterface { /** * {@inheritdoc} */ public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { $data = array( 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()) ); return new JsonResponse($data, Response::HTTP_FORBIDDEN); } }
  36. 36. /** * Class AuthenticationSuccessHandler * * @package AppBundleSecurity */ class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface { /** * @inheritdoc */ public function onAuthenticationSuccess(Request $request, TokenInterface $token) { return $this->handleAuthenticationSuccess($token->getUser()); } }
  37. 37. /** * Class AuthenticationSuccessHandler * @package AppBundleSecurity */ class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface { const SSL_KEY_PASSPHRASE = 'tests'; public function onAuthenticationSuccess(Request $request, TokenInterface $token) { return $this->handleAuthenticationSuccess($token->getUser()); } public function handleAuthenticationSuccess(UserInterface $user) { $jws = new SimpleJWS(array('alg' => 'RS256')); $jws->setPayload(array('sub' => $user->getUsername(), 'exp' => time() + 3600)); $privateKey = openssl_pkey_get_private("file://path_to_private.key", self::SSL_KEY_PASSPHRASE); $jws->sign($privateKey); return new JsonResponse(array('token' => $jws->getTokenString())); } }
  38. 38. # app/config/services.yml services: app.token_authenticator: class: AppBundleSecurityWebnetTokenAuthenticator
  39. 39. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { }
  40. 40. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { /** * @inheritdoc */ public function getCredentials(Request $request) { if (!$tokenValue = $request->headers->get('Authorization')) { // no token? Return null and no other methods will be called return; } $token = explode(' ', $tokenValue); try { return ['token' => SimpleJWS::load($token[1])]; } catch (Exception $e) { return; } } }
  41. 41. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { /** * @inheritdoc */ public function start(Request $request, AuthenticationException $authException = null) { $data = array('message' => 'Authentication Required'); return new JsonResponse($data, Response::HTTP_UNAUTHORIZED); } }
  42. 42. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { /** * @inheritdoc */ public function getCredentials(Request $request) { if (!$tokenValue = $request->headers->get('Authorization')) { // no token? Return null and no other methods will be called return; } $token = explode(' ', $tokenValue); try { return ['token' => SimpleJWS::load($token[1])]; } catch (Exception $e) { return; } } }
  43. 43. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { /** * @inheritdoc */ public function getUser($credentials, UserProviderInterface $userProvider) { $payload = $credentials['token']->getPayload(); if (!isset($payload['sub']) || !$payload['sub']) { return; } return $userProvider->loadUserByUsername($payload['sub']); } }
  44. 44. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { /** * @inheritdoc */ public function checkCredentials($credentials, UserInterface $user) { $publicKey = openssl_pkey_get_public("file://path_to_public.key"); // verify that the token is valid (exp) and had the same values return $credentials['token']->isValid($publicKey, 'RS256'); } }
  45. 45. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { /** * @inheritdoc */ public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { // on success, let the request continue return null; } /** * @inheritdoc */ public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { $data = array( 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()) ); return new JsonResponse($data, Response::HTTP_FORBIDDEN); } }
  46. 46. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { public function supportsRememberMe() { return false; } }
  47. 47. « There’s a bundle for that ! » o lexik/LexikJWTAuthenticationBundle o gesdinet/JWTRefreshTokenBundle (refresh token)
  48. 48.

Les web-services sont aujourd'hui au centre des SI de nos entreprises. Ils permettent de transmettre l'information entre des systèmes hétérogènes, à la fois au sein de l’entreprise mais également à l'extérieur, notamment et de plus en plus vers des systèmes mobiles. Or exposer cette information, potentiellement critique, pose la question de la sécurisation de ces échanges. Cette présentation sera l'occasion de présenter JWT, d'expliquer son fonctionnement et son implémentation au sein d'un projet Symfony 3.

Vues

Nombre de vues

1 597

Sur Slideshare

0

À partir des intégrations

0

Nombre d'intégrations

165

Actions

Téléchargements

42

Partages

0

Commentaires

0

Mentions J'aime

0

×