SlideShare a Scribd company logo
1 of 77
Download to read offline
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 Suppression
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 stateless
 Pas de session
 Appel isolé
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
 est normalement stateless
 Pas de session
 Appel isolé
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
Une API Web :
 expose de l’information potentiellement critique
 permet de manipuler cette information
 est normalement stateless
 doit être utilisée en HTTPS
 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 … Ohg2v5x6df2fFspoa1fdffds8
3 antoine … khHp5se8w2xf1t9823tz3
 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 non exploitable
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 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
 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
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 token JWT à l’application
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 createAuthenticatedToken(UserInterface $user, $providerKey);
}
namespace SymfonyComponentSecurityGuard;
abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface
{
public function createAuthenticatedToken(UserInterface $user, $providerKey);
}
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();
}
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();
}
namespace SymfonyComponentSecurityHttpEntryPoint;
interface AuthenticationEntryPointInterface
{
public function start(Request $request, AuthenticationException $authException = null);
}
#app/config/security.yml
security:
encoders:
SymfonyComponentSecurityCoreUserUserInterface: plaintext
providers:
in_memory:
memory:
users:
andre:
password: I_<3_Webnet
roles: ROLE_ADMIN
#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 }
# app/config/service.yml
services:
webnet_authentication.handler.authentication_success:
class: AppBundleSecurityAuthenticationSuccessHandler
arguments: []
webnet_authentication.handler.authentication_failure:
class: AppBundleSecurityAuthenticationFailureHandler
arguments: []
/**
* 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);
}
}
/**
* Class AuthenticationSuccessHandler
*
* @package AppBundleSecurity
*/
class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
{
/**
* @inheritdoc
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
return $this->handleAuthenticationSuccess($token->getUser());
}
}
/**
* 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()));
}
}
# app/config/services.yml
services:
app.token_authenticator:
class: AppBundleSecurityWebnetTokenAuthenticator
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthenticator
{
}
/**
* 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;
}
}
}
/**
* 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);
}
}
/**
* 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;
}
}
}
/**
* 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']);
}
}
/**
* 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');
}
}
/**
* 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);
}
}
/**
* Class WebnetAuthenticator
*
* @package AppBundleSecurity
*/
class WebnetAuthenticator extends AbstractGuardAuthenticator
{
public function supportsRememberMe()
{
return false;
}
}
« There’s a bundle for that ! »
o lexik/LexikJWTAuthenticationBundle
o gesdinet/JWTRefreshTokenBundle (refresh token)


More Related Content

What's hot

What's hot (20)

RESTful API development in Laravel 4 - Christopher Pecoraro
RESTful API development in Laravel 4 - Christopher PecoraroRESTful API development in Laravel 4 - Christopher Pecoraro
RESTful API development in Laravel 4 - Christopher Pecoraro
 
API Platform: Full Stack Framework Resurrection
API Platform: Full Stack Framework ResurrectionAPI Platform: Full Stack Framework Resurrection
API Platform: Full Stack Framework Resurrection
 
Creating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkCreating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform framework
 
Web service with Laravel
Web service with LaravelWeb service with Laravel
Web service with Laravel
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
 
Javascript laravel's friend
Javascript laravel's friendJavascript laravel's friend
Javascript laravel's friend
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 
Immutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaImmutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS Lambda
 
170517 damien gérard framework facebook
170517 damien gérard   framework facebook170517 damien gérard   framework facebook
170517 damien gérard framework facebook
 
WebGUI Developers Workshop
WebGUI Developers WorkshopWebGUI Developers Workshop
WebGUI Developers Workshop
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.com
 
Red5 - PHUG Workshops
Red5 - PHUG WorkshopsRed5 - PHUG Workshops
Red5 - PHUG Workshops
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
Introduction to laravel framework
Introduction to laravel frameworkIntroduction to laravel framework
Introduction to laravel framework
 
Web services with laravel
Web services with laravelWeb services with laravel
Web services with laravel
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreSymfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
 
From Ruby to Node.js
From Ruby to Node.jsFrom Ruby to Node.js
From Ruby to Node.js
 

Viewers also liked

Being an ally to trans
Being an ally to transBeing an ally to trans
Being an ally to trans
Pip Nosegroeg
 

Viewers also liked (19)

Introduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingIntroduction to CQRS and Event Sourcing
Introduction to CQRS and Event Sourcing
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your Niche
 
Construire Des Applications Cloud Natives - SymfonyLive Paris 2016
Construire Des Applications Cloud Natives - SymfonyLive Paris 2016Construire Des Applications Cloud Natives - SymfonyLive Paris 2016
Construire Des Applications Cloud Natives - SymfonyLive Paris 2016
 
IoT powered by PHP and streams - PHPExperience2017
IoT powered by PHP and streams - PHPExperience2017IoT powered by PHP and streams - PHPExperience2017
IoT powered by PHP and streams - PHPExperience2017
 
Essay about event driven architecture
Essay about event driven architectureEssay about event driven architecture
Essay about event driven architecture
 
Présentation de PHP
Présentation de PHPPrésentation de PHP
Présentation de PHP
 
Syntaxe du langage PHP
Syntaxe du langage PHPSyntaxe du langage PHP
Syntaxe du langage PHP
 
Structure de données en PHP
Structure de données en PHPStructure de données en PHP
Structure de données en PHP
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in php
 
OER World Map: Adolescence of a Community Platform
OER World Map: Adolescence of a Community PlatformOER World Map: Adolescence of a Community Platform
OER World Map: Adolescence of a Community Platform
 
Driving Member Engagement by Showing #VolunteerLove
Driving Member Engagement by Showing #VolunteerLoveDriving Member Engagement by Showing #VolunteerLove
Driving Member Engagement by Showing #VolunteerLove
 
The 4 Stages Of Learning
The 4 Stages Of LearningThe 4 Stages Of Learning
The 4 Stages Of Learning
 
テキスト1(公開版)
テキスト1(公開版)テキスト1(公開版)
テキスト1(公開版)
 
Oferta agregada y demanda agregada
Oferta agregada y demanda agregadaOferta agregada y demanda agregada
Oferta agregada y demanda agregada
 
Being an ally to trans
Being an ally to transBeing an ally to trans
Being an ally to trans
 
Legalthings e-book
Legalthings e-bookLegalthings e-book
Legalthings e-book
 
Ley de sustancias controladas y poder de estado
Ley de sustancias controladas y poder de estadoLey de sustancias controladas y poder de estado
Ley de sustancias controladas y poder de estado
 
Epidemiology of Preterm Birth
Epidemiology of Preterm BirthEpidemiology of Preterm Birth
Epidemiology of Preterm Birth
 

Similar to JWT - Sécurisez vos APIs

Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
Michael Peacock
 
Pentesting web applications
Pentesting web applicationsPentesting web applications
Pentesting web applications
Satish b
 
Lets have some fun with twilio open tok
Lets have some fun with   twilio open tokLets have some fun with   twilio open tok
Lets have some fun with twilio open tok
mirahman
 

Similar to JWT - Sécurisez vos APIs (20)

Sécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web  à l’aide du composant Security de SymfonySécurisation de vos applications web  à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de Symfony
 
RoadSec 2017 - Trilha AppSec - APIs Authorization
RoadSec 2017 - Trilha AppSec - APIs AuthorizationRoadSec 2017 - Trilha AppSec - APIs Authorization
RoadSec 2017 - Trilha AppSec - APIs Authorization
 
Kotlin server side frameworks
Kotlin server side frameworksKotlin server side frameworks
Kotlin server side frameworks
 
DEF CON 27 - ALVARO MUNOZ / OLEKSANDR MIROSH - sso wars the token menace
DEF CON 27 - ALVARO MUNOZ / OLEKSANDR MIROSH - sso wars the token menaceDEF CON 27 - ALVARO MUNOZ / OLEKSANDR MIROSH - sso wars the token menace
DEF CON 27 - ALVARO MUNOZ / OLEKSANDR MIROSH - sso wars the token menace
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API Documentation
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
Sécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de SymfonySécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de Symfony
 
Cloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFECloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFE
 
REST APIs in the context of single-page applications
REST APIs in the context of single-page applicationsREST APIs in the context of single-page applications
REST APIs in the context of single-page applications
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API Documentation
 
Strong Authentication in Web Application #SCS III
Strong Authentication in Web Application #SCS IIIStrong Authentication in Web Application #SCS III
Strong Authentication in Web Application #SCS III
 
Обмен учетными данными между iOS 8 приложениями и вебом, Константин Чернухо, ...
Обмен учетными данными между iOS 8 приложениями и вебом, Константин Чернухо, ...Обмен учетными данными между iOS 8 приложениями и вебом, Константин Чернухо, ...
Обмен учетными данными между iOS 8 приложениями и вебом, Константин Чернухо, ...
 
Designing JavaScript APIs
Designing JavaScript APIsDesigning JavaScript APIs
Designing JavaScript APIs
 
ASP.NET Single Sign On
ASP.NET Single Sign OnASP.NET Single Sign On
ASP.NET Single Sign On
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and Library
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Pentesting web applications
Pentesting web applicationsPentesting web applications
Pentesting web applications
 
CIS 2012 - Going Mobile with PingFederate and OAuth 2
CIS 2012 - Going Mobile with PingFederate and OAuth 2CIS 2012 - Going Mobile with PingFederate and OAuth 2
CIS 2012 - Going Mobile with PingFederate and OAuth 2
 
OWASP San Diego Training Presentation
OWASP San Diego Training PresentationOWASP San Diego Training Presentation
OWASP San Diego Training Presentation
 
Lets have some fun with twilio open tok
Lets have some fun with   twilio open tokLets have some fun with   twilio open tok
Lets have some fun with twilio open tok
 

Recently uploaded

Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
amilabibi1
 
If this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New NigeriaIf this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New Nigeria
Kayode Fayemi
 
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
Sheetaleventcompany
 

Recently uploaded (20)

Busty Desi⚡Call Girls in Sector 51 Noida Escorts >༒8448380779 Escort Service-...
Busty Desi⚡Call Girls in Sector 51 Noida Escorts >༒8448380779 Escort Service-...Busty Desi⚡Call Girls in Sector 51 Noida Escorts >༒8448380779 Escort Service-...
Busty Desi⚡Call Girls in Sector 51 Noida Escorts >༒8448380779 Escort Service-...
 
The workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdf
The workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdfThe workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdf
The workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdf
 
Presentation on Engagement in Book Clubs
Presentation on Engagement in Book ClubsPresentation on Engagement in Book Clubs
Presentation on Engagement in Book Clubs
 
Causes of poverty in France presentation.pptx
Causes of poverty in France presentation.pptxCauses of poverty in France presentation.pptx
Causes of poverty in France presentation.pptx
 
BDSM⚡Call Girls in Sector 93 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 93 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 93 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 93 Noida Escorts >༒8448380779 Escort Service
 
Dreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio IIIDreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio III
 
lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.
 
My Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle BaileyMy Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle Bailey
 
Air breathing and respiratory adaptations in diver animals
Air breathing and respiratory adaptations in diver animalsAir breathing and respiratory adaptations in diver animals
Air breathing and respiratory adaptations in diver animals
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
 
ICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdfICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdf
 
Dreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video TreatmentDreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video Treatment
 
Aesthetic Colaba Mumbai Cst Call girls 📞 7738631006 Grant road Call Girls ❤️-...
Aesthetic Colaba Mumbai Cst Call girls 📞 7738631006 Grant road Call Girls ❤️-...Aesthetic Colaba Mumbai Cst Call girls 📞 7738631006 Grant road Call Girls ❤️-...
Aesthetic Colaba Mumbai Cst Call girls 📞 7738631006 Grant road Call Girls ❤️-...
 
If this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New NigeriaIf this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New Nigeria
 
Report Writing Webinar Training
Report Writing Webinar TrainingReport Writing Webinar Training
Report Writing Webinar Training
 
BDSM⚡Call Girls in Sector 97 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 97 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 97 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 97 Noida Escorts >༒8448380779 Escort Service
 
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
 
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdfAWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
 
SaaStr Workshop Wednesday w/ Lucas Price, Yardstick
SaaStr Workshop Wednesday w/ Lucas Price, YardstickSaaStr Workshop Wednesday w/ Lucas Price, Yardstick
SaaStr Workshop Wednesday w/ Lucas Price, Yardstick
 
Introduction to Prompt Engineering (Focusing on ChatGPT)
Introduction to Prompt Engineering (Focusing on ChatGPT)Introduction to Prompt Engineering (Focusing on ChatGPT)
Introduction to Prompt Engineering (Focusing on ChatGPT)
 

JWT - Sécurisez vos APIs

  • 1.
  • 2.
  • 3.
  • 4. Architecte technique chez depuis 2011 +5 ans d’expérience sur une quinzaine de projets Symfony2 de tous types
  • 5. 1
  • 6.
  • 7. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information
  • 8. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information Edition Ajout Suppression
  • 9.
  • 10.
  • 11. CRUCIAL de veiller à une sécurité accrue de chaque API
  • 12. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  Pas de session  Appel isolé
  • 13. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  Pas de session  Appel isolé
  • 14. 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
  • 15. Une API Web :  expose de l’information potentiellement critique  permet de manipuler cette information  est normalement stateless  doit être utilisée en HTTPS
  • 16.
  • 17.  Authentification basée sur la session
  • 18. Inconvénients  CORS (Cross-origin resource sharing)  Évolutivité
  • 19.  Authentification basée sur les clefs d’API Pas de session
  • 20.  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
  • 21.  Authentification basée sur les clefs d’API Pas de session Gestion des clefs en bdd Pas de mécanisme d’expiration
  • 22.  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
  • 23. Solution idéale :  Stateless  Gestion de l’expiration  Auto-porteuse et sécurisée
  • 24. 2
  • 25.
  • 26.  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
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.  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
  • 32.
  • 33. JOSE : Javascript Object Signing and Encryption HMAC + SHA RSA + SHA ECDSA + SHA
  • 34.
  • 35.  Implémentation disponible pour la grande majorité des langages de développement
  • 36.
  • 37.
  • 38. 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
  • 39. Etape 2 à N :  L’application transmet le token JWT pour chaque transaction suivante en header des requêtes
  • 40.
  • 41. Quelle durée choisir ?  Pas de durée type  En moyenne : entre 5 min et 1 heure  Délai expiré :
  • 43.
  • 44.
  • 45. 3
  • 46.
  • 47. namespace SymfonyComponentSecurityGuard; abstract class AbstractGuardAuthenticator { public function createAuthenticatedToken(UserInterface $user, $providerKey); }
  • 48. namespace SymfonyComponentSecurityGuard; abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface { public function createAuthenticatedToken(UserInterface $user, $providerKey); }
  • 49. 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(); }
  • 50. 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(); }
  • 51. namespace SymfonyComponentSecurityHttpEntryPoint; interface AuthenticationEntryPointInterface { public function start(Request $request, AuthenticationException $authException = null); }
  • 52.
  • 54. #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 }
  • 55. # app/config/service.yml services: webnet_authentication.handler.authentication_success: class: AppBundleSecurityAuthenticationSuccessHandler arguments: [] webnet_authentication.handler.authentication_failure: class: AppBundleSecurityAuthenticationFailureHandler arguments: []
  • 56.
  • 57. /** * 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); } }
  • 58.
  • 59. /** * Class AuthenticationSuccessHandler * * @package AppBundleSecurity */ class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface { /** * @inheritdoc */ public function onAuthenticationSuccess(Request $request, TokenInterface $token) { return $this->handleAuthenticationSuccess($token->getUser()); } }
  • 60.
  • 61.
  • 62. /** * 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())); } }
  • 63.
  • 64.
  • 66. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { }
  • 67. /** * 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; } } }
  • 68. /** * 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); } }
  • 69. /** * 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; } } }
  • 70. /** * 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']); } }
  • 71. /** * 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'); } }
  • 72. /** * 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); } }
  • 73. /** * Class WebnetAuthenticator * * @package AppBundleSecurity */ class WebnetAuthenticator extends AbstractGuardAuthenticator { public function supportsRememberMe() { return false; } }
  • 74.
  • 75. « There’s a bundle for that ! » o lexik/LexikJWTAuthenticationBundle o gesdinet/JWTRefreshTokenBundle (refresh token)
  • 76.
  • 77.