SlideShare a Scribd company logo
1 of 38
Sécurisation de vos applications web
à l’aide du composant Security de Symfony
28 août 2018
https://vria.eu
contact@vria.eu
https://twitter.com/RiaVlad
RIABCHENKO Vladyslav
5+ ans full stack web-développeur
Certifié Symfony
Architecte technique à Webnet
Symfony 3
1. Symfony
2. Authentification artisanale
3. Firewall
4. Token anonyme
5. User provider
6. Authentication provider
7. HTTP Basic
8. Formulaire de connexion
Plan
Symfony 4
Authentification est un processus permettant à l’application de s’assurer que la requête
a été faite par un utilisateur légitime.
C’est une confirmation de son identité grâce à des identifiants.
Identification est une sélection d’utilisateur grâce à son identifiant.
Autorisation est une vérification des droits d’accès d’un utilisateur sur une ressource en
se basant sur une politique d’accès.
Auth simple 5
Authentifier chaque requête à l’application à l’aide d’un identifiant et d’un
mot de passe.Tâche 1
Front controller
Token
public/index.php reçoit toutes les requêtes client quelque soit le
path et les paramètres
HttpFoundation
Composant de Symfony qui fournit la couche orientée-objet pour
HTTP : Request, Response, Session, etc.
Conserve des données sur l’utilisateur :
• Objet d’utilisateur
• Username
• Credentials
• Roles
• Authentifié ou pas
SymfonyComponentSecurityCoreAuthenticationToken
6
Security listeners
Token Conserve des données sur l’utilisateur
+ getUser()
+ getUsername()
+ getCredentials()
+ isAuthenticated()
+ getRoles()
TokenInterface
+ getProviderKey()
UsernamePasswordToken
+ getSecret()
AnonymousToken
Listeners qui extraient les identifiants et les vérifient.
Ils créent ensuite un Token puis le stockent dans le Token storage.
Token storage Objet/service qui contient un Token
Auth simple
7
// public/index.php
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage;
use SymfonyComponentHttpFoundationResponse;
$request = Request::createFromGlobals(); // HTTP request
$tokenStorage = new TokenStorage(); // Service that stores user token
// Call security listener on every request.
$securityListener = new AppSecuritySecurityListener($tokenStorage);
$securityListener->onRequest($request);
// Any code you can imagine to generate a response.
// You can deny access if no token were set.
$token = $tokenStorage->getToken();
$response = new Response(
'Request uri: '.$request->getRequestUri().'<br>'
.'Token: '.(is_object($token) ? get_class($token) : gettype($token)).'<br>'
.'Username: '.($token ? $token->getUsername(): 'NULL')
);
$response->send(); // Send response
Auth simple
8
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface;
use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken;
class SecurityListener
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function onRequest(Request $request)
{
$user = $request->query->get('auth_user');
$password = $request->query->get('auth_pw');
if ($user === 'vlad' && $password === 'pass') {
// Credentials are valid.
// Create a token with user object, credentials, provider key and roles
$token = new UsernamePasswordToken($user, $password, 'main', ['ROLE_USER']);
// Save it to token storage
$this->tokenStorage->setToken($token);
}
}
}
Auth simple
Firewall 9
Centraliser l’authentification dans un firewall afin de pouvoir utiliser
plusieurs systèmes d’authentification.Tâche 2
HttpKernel
Le composant de Symfony qui fournit un processus structuré pour
convertir Request en Response en utilisant EventDispatcher.
EventDispatcher
Le composant de Symfony qui permet aux composants de
communiquer entre eux à l’aide d’événements.
Request ResponseResolve controller Execute controller
EXCEPTIONEvent Dispatcher
// public/index.php
use SymfonyComponentEventDispatcherEventDispatcher;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpKernelHttpKernel;
use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage;
$request = Request::createFromGlobals(); // HTTP request.
$tokenStorage = new TokenStorage(); // Service that stores user token.
$dispatcher = new EventDispatcher();
// Controller creates a response to send to the user.
$controller = new AppController($request, $tokenStorage);
$controllerResolver = new AppControllerResolver([$controller, 'defaultAction']);
// kernel is in charge of converting a Request into a Response by using the event dispatcher.
$kernel = new HttpKernel($dispatcher, $controllerResolver);
// We will add security listeners to dispatcher in few minutes.
$response = $kernel->handle($request);
$response->send();
10Firewall
Le Front controller crée $kernel et lui demande de traiter la requête.
11
Kernel demande à ControllerResolver de renvoyer le contrôleur en fonction de la
requête. C’est l’emplacement idéal pour la logique de Routing.
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpKernelControllerControllerResolverInterface;
class ControllerResolver implements ControllerResolverInterface
{
/** @var callable */
private $default;
public function __construct(callable $default)
{
$this->default = $default;
}
public function getController(Request $request)
{
return $this->default;
}
}
Firewall
12
class Controller
{
/** @var Request */
private $request;
/** @var TokenStorageInterface */
private $tokenStorage;
public function defaultAction()
{
$token = $this->tokenStorage->getToken();
return new Response(
'Request uri: '.$this->request->getRequestUri().'<br>'
.'Token: '.(is_object($token) ? get_class($token) : gettype($token)).'<br>'
.'Username: '.($token ? $token->getUsername(): 'NULL')
);
}
}
La méthode Controller::defaultAction est un contrôleur qui sera exécuté par Kernel.
Firewall
SymfonyComponentSecurityHttp
13
- map: array
+ getListeners(Request $request)
Firewall
- map: FirewallMap
+ onKernelRequest(GetResponseEvent $event)
FirewallMap
RequestMatcher
- path: string
=>
][
Le firewall est un listener de l’événement
REQUEST.
Il permet d’implémenter des stratégies
d’authentification en fonction de la
requête.
FirewallMap renvoie les listeners
configurés pour le requête spécifique.
ListenerInterface
+ handle(GetResponseEvent $event) , …
Firewall
14
RequestMatcher
- path = ^/back
- ips = [192.0.0.4]
=>
][ BasicAuthenticationListener
RequestMatcher
- path: ^/customer
=>
][ ContextListener
,
SimpleFormAuthenticationListener
RequestMatcher =>
][AnonymousAuthenticationListener
Utiliser l’authentification HTTP basic pour toutes les requêtes qui commencent par /back
Authentifier les requêtes qui commencent par /customer à l’aide d’un formulaire classique
Authentifier toutes les autres requêtes comme anonymes
Firewall
15
// public/index.php
use SymfonyComponentHttpFoundationRequestMatcher;
use SymfonyComponentSecurityHttpFirewall;
use SymfonyComponentSecurityHttpFirewallMap;
// ...
// Create main security listener that handles authentication.
$securityListener = new AppSecurityMainSecurityListener($tokenStorage);
// Create firewall map and add main security listener under URLs starting with "/main".
$firewallMap = new FirewallMap();
$firewallMap->add(new RequestMatcher('^/main'), [$securityListener]);
// Create firewall and add it to dispatcher.
$firewall = new Firewall($firewallMap, $dispatcher);
$dispatcher->addSubscriber($firewall);
// ...
Firewall attends l’événement REQUEST pour exécuter MainSecurityListener si le path de
la requête commence par /main.
Firewall
16
use SymfonyComponentHttpKernelEventGetResponseEvent;
use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface;
use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken;
use SymfonyComponentSecurityHttpFirewallListenerInterface;
class MainSecurityListener implements ListenerInterface
{
/** @var TokenStorageInterface */
private $tokenStorage;
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
$user = $request->query->get('auth_user');
$password = $request->query->get('auth_pw');
if ($user === 'vlad' && $password === 'pass') {
$token = new UsernamePasswordToken($user, $password, 'main', ['ROLE_USER']);
$this->tokenStorage->setToken($token);
}
}
}
MainSecurityListener implémente désormais ListenerInterface.
Firewall
App
SymfonyComponentSecurityHttpFirewall
anon. 17
Permettre aux utilisateurs de s’authentifier comme des anonymes.Tâche 3
RequestMatcher
- path = ^/main =>
][
MainSecurityListener
AnonymousAuthenticationListener
// public/index.php
use SymfonyComponentHttpFoundationRequestMatcher;
use SymfonyComponentSecurityHttpFirewallMap;
use SymfonyComponentSecurityHttpFirewallAnonymousAuthenticationListener;
// ...
// Create a security listener that adds anonymous token if none is already present.
$anonListener = new AnonymousAuthenticationListener($tokenStorage, 'secret');
// Create firewall map and add main security listener under URLs starting with "/main".
$firewallMap = new FirewallMap();
$firewallMap->add(new RequestMatcher('^/main'), [$securityListener, $anonListener]);
User provider 18
Abstraire le moyen de récupération des utilisateurs et déplacer cette logique
en dehors des security listeners.Tâche 4
SymfonyComponentSecurityCoreUser
UserProviderInterface
+ loadUserByUsername($username): UserInterface
+ refreshUser(UserInterface $user)
+ supportsClass($class)
Security Listener
- userProvider
+ loadUserByUsername($username):User
UserInterface
+ getUsername()
+ getRoles()
+ getPassword()
+ getSalt()
+ eraseCredentials()
+ isEnabled()
UserInMemoryUserProvider
19
use SymfonyComponentHttpKernelEventGetResponseEvent;
use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken;
use SymfonyComponentSecurityCoreExceptionUsernameNotFoundException;
use SymfonyComponentSecurityCoreUserUserProviderInterface;
use SymfonyComponentSecurityHttpFirewallListenerInterface;
class MainSecurityListener implements ListenerInterface
{
/** @var UserProviderInterface */
private $userProvider;
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
$username = $request->query->get('auth_user');
$password = $request->query->get('auth_pw');
try {
$user = $this->userProvider->loadUserByUsername($username);
if ($user->getPassword() === $password) {
$token = new UsernamePasswordToken($user, $password, 'main', $user->getRoles());
$this->tokenStorage->setToken($token);
}
} catch (UsernameNotFoundException $e) {
}
}
}
User provider
20
// public/index.php
use SymfonyComponentEventDispatcherEventDispatcher;
use SymfonyComponentHttpFoundationRequestMatcher;
use SymfonyComponentSecurityHttpFirewallMap;
use SymfonyComponentSecurityHttpFirewall;
use SymfonyComponentSecurityCoreUserInMemoryUserProvider;
// ...
// Create user provider that will be used by authentication listener.
$mainUserProvider = new InMemoryUserProvider([
'vlad' => ['password' => 'pass', 'roles' => ['ROLE_USER’]],
]);
// Create main security listener that handles authentication.
$mainSecurityListener = new AppSecurityMainSecurityListener($tokenStorage, $mainUserProvider);
// Create firewall map and add main security listener under URLs starting with "/main".
$firewallMap = new FirewallMap();
$firewallMap->add(new RequestMatcher('^/main'), [$mainSecurityListener, $anonListener]);
// ...
User provider
Création d’un user provider pour main security listener.
App
21Auth provider
Ajouter l’encodage du mot de passe, n’accepter que des utilisateurs activés.
Déplacer la logique d’authentification en dehors des security listeners.Tâche 5
- tokenStorage
- authenticationManager
SymfonyComponentSecurityCoreAuthentication
AuthenticationManagerInterface
+ authenticate(TokenInterface $token)
MainSecurityListener
̶ Être rappelé par Firewall pendant l’événement
REQUEST
̶ Extraire l’identifiant et le mot de passe
̶ Créer le token non authentifié
̶ Passer le token à l’authentification manager
̶ Mettre le token authentifié dans le token storage
̶ Récupérer l’utilisateur grâce à l’identifiant et à
l’aide de user provider
̶ Vérifier le mot de passe à l’aide de password
encoder
̶ Vérifier les autres paramètres
̶ Renvoyer le token authentifié
$token->setAuthenticated(true)
créer un nouveau token
SymfonyComponentSecurityCoreAuthentication
22Auth provider
Provider
DaoAuthenticationProvider
- userProvider
- encoderFactory
- userChecker
AuthenticationManagerInterface
+ authenticate(TokenInterface $token)
SymfonyComponentSecurityCoreUser
UserProviderInterface
+ loadUserByUsername($username)
+ refreshUser(UserInterface $user)
+ supportsClass($class)
+ loadUserByUsername($username):User
InMemoryUserProvider
SymfonyComponentSecurityCoreAuthentication
23Auth provider
Provider
DaoAuthenticationProvider
- userProvider
- encoderFactory
- userChecker
SymfonyComponentSecurityCoreEncoder
EncoderFactoryInterface
+ getEncoder($user): PasswordEncoderInterface
PasswordEncoderInterface
+ encodePassword($raw, $salt)
+ isPasswordValid($encoded, $raw, $salt)
- cost: int
BCryptPasswordEncoder
- encoders: array
EncoderFactory
SymfonyComponentSecurityCoreAuthentication
24Auth provider
Provider
DaoAuthenticationProvider
AuthenticationManagerInterface
+ authenticate(TokenInterface $token)
SymfonyComponentSecurityCoreUser
UserChecker
+ checkPreAuth(UserInterface $user)
+ checkPostAuth(UserInterface $user)
UserCheckerInterface
- userProvider
- encoderFactory
- userChecker
25Auth provider
use SymfonyComponentSecurityCoreAuthenticationAuthenticationManagerInterface;
use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
class MainSecurityListener implements ListenerInterface
{
/** @var AuthenticationManagerInterface */
private $authenticationManager;
public function handle(GetResponseEvent $event)
{
// Extract authentication credentials.
if ($username && $credentials) {
try {
// Token is not authenticated because no role is passed.
$token = new UsernamePasswordToken($username, $credentials, 'main');
// Try to authenticate the token.
// If there is an authentication error an AuthenticationException is thrown.
$token = $this->authenticationManager->authenticate($token);
// Add authenticated token to storage.
$this->tokenStorage->setToken($token);
} catch (AuthenticationException $e) {}
}
}
}
26Auth provider
use SymfonyComponentSecurityCoreAuthenticationProviderDaoAuthenticationProvider;
use SymfonyComponentSecurityCoreEncoderBCryptPasswordEncoder;
// Create user provider that will be used by authentication listener.
$mainUserProvider = new InMemoryUserProvider([
'vlad' => [
'password' => '$2y$10$zDUW3BF4T5ZVloDZqp0SN.1Ic4DG3xfxHUDXWkkpvaP0G8qXnq', // encoded 'pass'
'roles' => ['ROLE_USER'],
'enabled' => true
]
]);
// And object that checks whether a user is non-locked, enabled, not expired, etc.
$mainUserChecker = new SymfonyComponentSecurityCoreUserUserChecker();
// A factory that specifies encoding algorithm to each user class.
$encoderFactory = new SymfonyComponentSecurityCoreEncoderEncoderFactory([
SymfonyComponentSecurityCoreUserUser::class => new BCryptPasswordEncoder(10)
]);
// Create a provider to which security listener will delegate an authentication.
$mainAuthProvider = new DaoAuthenticationProvider(
$mainUserProvider, $mainUserChecker, 'main', $encoderFactory
);
// Create main security listener that handles authentication.
$mainSecurityListener = new AppSecurityMainSecurityListener($tokenStorage, $mainAuthProvider);
27HTTP basic auth
Mettre en place l’authentification HTTP, laisser passer seulement les
utilisateurs connectés.Tâche 6
SymfonyComponentSecurityHttpFirewall
- tokenStorage
- authenticationManager
BasicAuthenticationListener
- tokenStorage
- accessDecisionManager
AccessListener
RequestMatcher
- path: ^/main
=>
Extraire l’identifiant et le mot de
passe de l'en-tête Authorization.
Créer le token, l'authentifier, le
sauvegarder dans token storage.
Lancer une exception si les
credentials ne sont pas valides. Lancer une exception si le token
n’est pas présent ou s’il ne
respecte pas les règles d’accès.
28
SymfonyComponentSecurityHttpEntryPoint
+ start(Request $request, $authException): Response
AuthenticationEntryPointInterface
- realmName: string
BasicAuthenticationEntryPoint
Lors de l'exception d’authentification (accès anonyme ou identifiants non valides) il faut
aider l’utilisateur à (re-)commencer l’authentification.
SymfonyComponentSecurityHttpFirewall
- tokenStorage
- authenticationManager
- authenticationEntryPoint
BasicAuthenticationListener
Event Dispatcher
- Kernel::EXCEPTION => [...]
- authenticationEntryPoint
ExceptionListener
HTTP basic auth
29
use SymfonyComponentHttpFoundationRequestMatcher;
use SymfonyComponentSecurityHttpAccessMap;
use SymfonyComponentSecurityHttpFirewallMap;
use SymfonyComponentSecurityHttpFirewallBasicAuthenticationListener;
use SymfonyComponentSecurityHttpFirewallAccessListener;
use SymfonyComponentSecurityHttpEntryPointBasicAuthenticationEntryPoint;
use SymfonyComponentSecurityCoreAuthorizationAccessDecisionManager;
// Entry point helps user to authenticate.
$basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint('Secured area');
// Create HTTP basic security listener that extracts credentials from headers (RFC 7617).
$mainSecurityListener = new BasicAuthenticationListener(
$tokenStorage, $mainAuthProvider, 'main', $basicAuthenticationEntryPoint
);
// Access listener will throw an exception when no token is already present.
$accessDecisionManager = new AccessDecisionManager();
$accessMap = new AccessMap();
$accessListener = new AccessListener(
$tokenStorage, $accessDecisionManager, $accessMap, $mainAuthProvider
);
// Create firewall map and add main security listener under URLs starting with "/main".
$firewallMap = new FirewallMap();
$firewallMap->add(new RequestMatcher('^/main'), [$mainSecurityListener, $accessListener]);
// ...
HTTP basic auth
30
use SymfonyComponentSecurityHttpHttpUtils;
use SymfonyComponentSecurityCoreAuthenticationAuthenticationTrustResolver;
use SymfonyComponentSecurityCoreAuthenticationTokenAnonymousToken;
use SymfonyComponentSecurityCoreAuthenticationTokenRememberMeToken;
use SymfonyComponentHttpKernelKernelEvents;
// ...
// ExceptionListener catches authentication exception and converts them to Response instance.
// In this case it invites user to enter its credentials by returning 401 response.
$authTrustResolver = new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class);
$httpUtils = new HttpUtils();
$exceptionListener = new ExceptionListener(
$tokenStorage, $authTrustResolver, $httpUtils, 'main', $basicAuthenticationEntryPoint
);
$dispatcher->addListener(KernelEvents::EXCEPTION, array($exceptionListener, 'onKernelException'), 1);
// ...
HTTP basic auth
31Formulaire de connexion
Mettre en place l’authentification par le formulaire de connexion pour une
autre partie de site.Tâche 7
SymfonyComponentSecurityHttpFirewall
- tokenStorage
- userProviders
ContextListener
- tokenStorage
- accessDecisionManager
- options
- successHandler
- failureHandler
UsernamePasswordFormAuthenticationListener
RequestMatcher
- path: ^/front
=>
+ handle(GetResponseEvent $event)
+ onKernelResponse(FilterResponseEvent $event)
+ handle(GetResponseEvent $event)
Récupérer le token d’une session
lors de l’événement REQUEST.
Sauvegarder le token dans une
session lors de l’événement
RESPONSE.
Authentifier l’utilisateur
seulement quand le formulaire de
connexion est envoyé
(POST sur /front/login_check).
32Formulaire de connexion
use SymfonyComponentHttpFoundationResponse;
class Controller
{
public function loginFormAction()
{
return new Response(<<<END
<form action="/front/login_check" method="POST">
<input type="text" name="_username" placeholder="username">
<input type="password" name="_password" placeholder="password">
<input type="submit">
</form>
END
);
}
public function defaultAction()
{
$token = $this->tokenStorage->getToken();
$user = $token ? $token->getUser() : null;
// ...
}
}
Nouvelle action pour visualiser le formulaire de conexion : POST sur /front/login_check.
33Formulaire de connexion
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpKernelControllerControllerResolverInterface;
class ControllerResolver implements ControllerResolverInterface
{
/** @var callable[] */
private $routes;
/** @var callable */
private $default;
public function getController(Request $request)
{
foreach ($this->routes as $pattern => $controller) {
if (preg_match($pattern, $request->getPathInfo())) {
return $controller;
}
}
return $this->default;
}
}
La nouvelle action sera appelée quand la requête est faite sur /font/login.
34Formulaire de connexion
// public/index.php
use SymfonyComponentEventDispatcherEventDispatcher;
use SymfonyComponentHttpKernelHttpKernel;
// ...
// Controller creates a response to send to the user.
$controller = new AppController($request, $tokenStorage);
$controllerResolver = new AppControllerResolver(
['/^/front/login$/' => [$controller, 'loginFormAction']],
[$controller, 'defaultAction']
);
// Kernel is in charge of converting a Request into a Response by using the event dispatcher.
$kernel = new HttpKernel($dispatcher, $controllerResolver);
// ...
La nouvelle action sera appelée quand la requête est faite sur /font/login.
35Formulaire de connexion
// public/index.php
use SymfonyComponentSecurityHttpFirewallContextListener;
// ...
// ContextListener retrieves previously authenticated token from the session during REQUEST event.
// It also saves token during RESPONSE event.
$contextListener = new ContextListener(
$tokenStorage, [$mainUserProvider], 'front', null, $dispatcher
);
// ...
Context security listener :
36Formulaire de connexion
use SymfonyComponentSecurityHttpAuthenticationDefaultAuthenticationSuccessHandler;
use SymfonyComponentSecurityHttpAuthentication DefaultAuthenticationFailureHandler;
use SymfonyComponentSecurityHttpFirewallUsernamePasswordFormAuthenticationListener;
use SymfonyComponentSecurityHttpSessionSessionAuthenticationStrategy;
$sessionAuthenticationStrategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE);
$successHandler = new DefaultAuthenticationSuccessHandler(
$httpUtils, ['default_target_path' => '/front/success’]
);
$failureHandler = new DefaultAuthenticationFailureHandler(
$kernel, $httpUtils, ['login_path' => '/front/login’]
);
// Listens for login form being send (POST to '/front/login_check').
// It extracts credentials, creates token, authenticates it and puts it to the token storage.
$formAuthListener = new UsernamePasswordFormAuthenticationListener(
$tokenStorage,
$frontAuthProvider,
$sessionAuthenticationStrategy,
$httpUtils,
'front',
$successHandler, // Redirect user to '/front/success' if credentials are valid
$failureHandler, // Redirect user to '/front/login' if credentials are invalid
['check_path' => '/front/login_check’, 'post_only' => true] // Act only on POST to '/front/login_check'
);
37Formulaire de connexion
// public/index.php
use SymfonyComponentHttpFoundationRequestMatcher;
use SymfonyComponentSecurityHttpFirewallMap;
// ...
$firewallMap = new FirewallMap();
$firewallMap->add(new RequestMatcher('^/main'), [$mainSecurityListener, $accessListener]);
$firewallMap->add(new RequestMatcher('^/front'), [$contextListener, $formAuthListener]);
// ...
Ajout de security listeners dans le Firewall :
Merci pour votre attention
Le code de cette présentation :
https://github.com/vria/symfony-security-component-use

More Related Content

What's hot

Php vulnerability presentation
Php vulnerability presentationPhp vulnerability presentation
Php vulnerability presentationSqa Enthusiast
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire playerMarcin Czarnecki
 
Symfony without the framework
Symfony without the frameworkSymfony without the framework
Symfony without the frameworkGOG.com dev team
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0Henrique Moody
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
Implementing OAuth with PHP
Implementing OAuth with PHPImplementing OAuth with PHP
Implementing OAuth with PHPLorna Mitchell
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Elixir Paris Meetup
Elixir Paris MeetupElixir Paris Meetup
Elixir Paris MeetupJoan Zapata
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien Potencier
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionAdam Trachtenberg
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 

What's hot (20)

Php e Cassandra
Php e Cassandra Php e Cassandra
Php e Cassandra
 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 
Php vulnerability presentation
Php vulnerability presentationPhp vulnerability presentation
Php vulnerability presentation
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire player
 
Symfony without the framework
Symfony without the frameworkSymfony without the framework
Symfony without the framework
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 
Php Security
Php SecurityPhp Security
Php Security
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
Implementing OAuth with PHP
Implementing OAuth with PHPImplementing OAuth with PHP
Implementing OAuth with PHP
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
New in php 7
New in php 7New in php 7
New in php 7
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Elixir Paris Meetup
Elixir Paris MeetupElixir Paris Meetup
Elixir Paris Meetup
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 

Similar to Secure your web apps with Symfony Security component

JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIsJWT - Sécurisez vos APIs
JWT - Sécurisez vos APIsAndré Tapia
 
How to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health AppHow to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health AppBen Adida
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and LibraryKenji Otsuka
 
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 menaceFelipe Prado
 
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 2scotttomilson
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Implementing application security using the .net framework
Implementing application security using the .net frameworkImplementing application security using the .net framework
Implementing application security using the .net frameworkLalit Kale
 
Building a Microgateway in Ballerina_KubeCon 2108
Building a Microgateway in Ballerina_KubeCon 2108Building a Microgateway in Ballerina_KubeCon 2108
Building a Microgateway in Ballerina_KubeCon 2108Ballerina
 
WP Passkey: Passwordless Authentication on WordPress
WP Passkey: Passwordless Authentication on WordPressWP Passkey: Passwordless Authentication on WordPress
WP Passkey: Passwordless Authentication on WordPressWordPress
 
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)danwrong
 
Java Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application SecurityJava Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application SecurityIMC Institute
 
How to implement authorization in your backend with AWS IAM
How to implement authorization in your backend with AWS IAMHow to implement authorization in your backend with AWS IAM
How to implement authorization in your backend with AWS IAMProvectus
 
Securing your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris KelloggSecuring your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris KelloggStreamNative
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring SecurityDzmitry Naskou
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSChih-Hsuan Kuo
 
OAuth 2.0 – A standard is coming of age by Uwe Friedrichsen
OAuth 2.0 – A standard is coming of age by Uwe FriedrichsenOAuth 2.0 – A standard is coming of age by Uwe Friedrichsen
OAuth 2.0 – A standard is coming of age by Uwe FriedrichsenCodemotion
 
OAuth2 and OpenID with Spring Boot
OAuth2 and OpenID with Spring BootOAuth2 and OpenID with Spring Boot
OAuth2 and OpenID with Spring BootGeert Pante
 

Similar to Secure your web apps with Symfony Security component (20)

JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIsJWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
 
How to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health AppHow to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health App
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and Library
 
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
 
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
 
Rolebased security
Rolebased securityRolebased security
Rolebased security
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Implementing application security using the .net framework
Implementing application security using the .net frameworkImplementing application security using the .net framework
Implementing application security using the .net framework
 
Building a Microgateway in Ballerina_KubeCon 2108
Building a Microgateway in Ballerina_KubeCon 2108Building a Microgateway in Ballerina_KubeCon 2108
Building a Microgateway in Ballerina_KubeCon 2108
 
WP Passkey: Passwordless Authentication on WordPress
WP Passkey: Passwordless Authentication on WordPressWP Passkey: Passwordless Authentication on WordPress
WP Passkey: Passwordless Authentication on WordPress
 
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
 
Java Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application SecurityJava Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application Security
 
How to implement authorization in your backend with AWS IAM
How to implement authorization in your backend with AWS IAMHow to implement authorization in your backend with AWS IAM
How to implement authorization in your backend with AWS IAM
 
Securing your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris KelloggSecuring your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris Kellogg
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OS
 
OAuth 2.0 – A standard is coming of age by Uwe Friedrichsen
OAuth 2.0 – A standard is coming of age by Uwe FriedrichsenOAuth 2.0 – A standard is coming of age by Uwe Friedrichsen
OAuth 2.0 – A standard is coming of age by Uwe Friedrichsen
 
OAuth2 and OpenID with Spring Boot
OAuth2 and OpenID with Spring BootOAuth2 and OpenID with Spring Boot
OAuth2 and OpenID with Spring Boot
 
State management
State managementState management
State management
 
TLDR - OAuth
TLDR - OAuthTLDR - OAuth
TLDR - OAuth
 

More from Vladyslav Riabchenko

Modèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratiqueModèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratiqueVladyslav Riabchenko
 
SOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsSOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsVladyslav Riabchenko
 
Versionning sémantique et Composer
Versionning sémantique et ComposerVersionning sémantique et Composer
Versionning sémantique et ComposerVladyslav Riabchenko
 
Injection de dépendances dans Symfony >= 3.3
Injection de dépendances dans Symfony >= 3.3Injection de dépendances dans Symfony >= 3.3
Injection de dépendances dans Symfony >= 3.3Vladyslav Riabchenko
 
Les patrons de conception du composant Form
Les patrons de conception du composant FormLes patrons de conception du composant Form
Les patrons de conception du composant FormVladyslav Riabchenko
 

More from Vladyslav Riabchenko (6)

Modèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratiqueModèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratique
 
SOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsSOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applications
 
Git
GitGit
Git
 
Versionning sémantique et Composer
Versionning sémantique et ComposerVersionning sémantique et Composer
Versionning sémantique et Composer
 
Injection de dépendances dans Symfony >= 3.3
Injection de dépendances dans Symfony >= 3.3Injection de dépendances dans Symfony >= 3.3
Injection de dépendances dans Symfony >= 3.3
 
Les patrons de conception du composant Form
Les patrons de conception du composant FormLes patrons de conception du composant Form
Les patrons de conception du composant Form
 

Recently uploaded

The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 

Recently uploaded (20)

The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

Secure your web apps with Symfony Security component

  • 1. Sécurisation de vos applications web à l’aide du composant Security de Symfony 28 août 2018
  • 2. https://vria.eu contact@vria.eu https://twitter.com/RiaVlad RIABCHENKO Vladyslav 5+ ans full stack web-développeur Certifié Symfony Architecte technique à Webnet
  • 3. Symfony 3 1. Symfony 2. Authentification artisanale 3. Firewall 4. Token anonyme 5. User provider 6. Authentication provider 7. HTTP Basic 8. Formulaire de connexion Plan
  • 4. Symfony 4 Authentification est un processus permettant à l’application de s’assurer que la requête a été faite par un utilisateur légitime. C’est une confirmation de son identité grâce à des identifiants. Identification est une sélection d’utilisateur grâce à son identifiant. Autorisation est une vérification des droits d’accès d’un utilisateur sur une ressource en se basant sur une politique d’accès.
  • 5. Auth simple 5 Authentifier chaque requête à l’application à l’aide d’un identifiant et d’un mot de passe.Tâche 1 Front controller Token public/index.php reçoit toutes les requêtes client quelque soit le path et les paramètres HttpFoundation Composant de Symfony qui fournit la couche orientée-objet pour HTTP : Request, Response, Session, etc. Conserve des données sur l’utilisateur : • Objet d’utilisateur • Username • Credentials • Roles • Authentifié ou pas
  • 6. SymfonyComponentSecurityCoreAuthenticationToken 6 Security listeners Token Conserve des données sur l’utilisateur + getUser() + getUsername() + getCredentials() + isAuthenticated() + getRoles() TokenInterface + getProviderKey() UsernamePasswordToken + getSecret() AnonymousToken Listeners qui extraient les identifiants et les vérifient. Ils créent ensuite un Token puis le stockent dans le Token storage. Token storage Objet/service qui contient un Token Auth simple
  • 7. 7 // public/index.php use SymfonyComponentHttpFoundationRequest; use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage; use SymfonyComponentHttpFoundationResponse; $request = Request::createFromGlobals(); // HTTP request $tokenStorage = new TokenStorage(); // Service that stores user token // Call security listener on every request. $securityListener = new AppSecuritySecurityListener($tokenStorage); $securityListener->onRequest($request); // Any code you can imagine to generate a response. // You can deny access if no token were set. $token = $tokenStorage->getToken(); $response = new Response( 'Request uri: '.$request->getRequestUri().'<br>' .'Token: '.(is_object($token) ? get_class($token) : gettype($token)).'<br>' .'Username: '.($token ? $token->getUsername(): 'NULL') ); $response->send(); // Send response Auth simple
  • 8. 8 use SymfonyComponentHttpFoundationRequest; use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; class SecurityListener { private $tokenStorage; public function __construct(TokenStorageInterface $tokenStorage) { $this->tokenStorage = $tokenStorage; } public function onRequest(Request $request) { $user = $request->query->get('auth_user'); $password = $request->query->get('auth_pw'); if ($user === 'vlad' && $password === 'pass') { // Credentials are valid. // Create a token with user object, credentials, provider key and roles $token = new UsernamePasswordToken($user, $password, 'main', ['ROLE_USER']); // Save it to token storage $this->tokenStorage->setToken($token); } } } Auth simple
  • 9. Firewall 9 Centraliser l’authentification dans un firewall afin de pouvoir utiliser plusieurs systèmes d’authentification.Tâche 2 HttpKernel Le composant de Symfony qui fournit un processus structuré pour convertir Request en Response en utilisant EventDispatcher. EventDispatcher Le composant de Symfony qui permet aux composants de communiquer entre eux à l’aide d’événements. Request ResponseResolve controller Execute controller EXCEPTIONEvent Dispatcher
  • 10. // public/index.php use SymfonyComponentEventDispatcherEventDispatcher; use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpKernelHttpKernel; use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage; $request = Request::createFromGlobals(); // HTTP request. $tokenStorage = new TokenStorage(); // Service that stores user token. $dispatcher = new EventDispatcher(); // Controller creates a response to send to the user. $controller = new AppController($request, $tokenStorage); $controllerResolver = new AppControllerResolver([$controller, 'defaultAction']); // kernel is in charge of converting a Request into a Response by using the event dispatcher. $kernel = new HttpKernel($dispatcher, $controllerResolver); // We will add security listeners to dispatcher in few minutes. $response = $kernel->handle($request); $response->send(); 10Firewall Le Front controller crée $kernel et lui demande de traiter la requête.
  • 11. 11 Kernel demande à ControllerResolver de renvoyer le contrôleur en fonction de la requête. C’est l’emplacement idéal pour la logique de Routing. use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpKernelControllerControllerResolverInterface; class ControllerResolver implements ControllerResolverInterface { /** @var callable */ private $default; public function __construct(callable $default) { $this->default = $default; } public function getController(Request $request) { return $this->default; } } Firewall
  • 12. 12 class Controller { /** @var Request */ private $request; /** @var TokenStorageInterface */ private $tokenStorage; public function defaultAction() { $token = $this->tokenStorage->getToken(); return new Response( 'Request uri: '.$this->request->getRequestUri().'<br>' .'Token: '.(is_object($token) ? get_class($token) : gettype($token)).'<br>' .'Username: '.($token ? $token->getUsername(): 'NULL') ); } } La méthode Controller::defaultAction est un contrôleur qui sera exécuté par Kernel. Firewall
  • 13. SymfonyComponentSecurityHttp 13 - map: array + getListeners(Request $request) Firewall - map: FirewallMap + onKernelRequest(GetResponseEvent $event) FirewallMap RequestMatcher - path: string => ][ Le firewall est un listener de l’événement REQUEST. Il permet d’implémenter des stratégies d’authentification en fonction de la requête. FirewallMap renvoie les listeners configurés pour le requête spécifique. ListenerInterface + handle(GetResponseEvent $event) , … Firewall
  • 14. 14 RequestMatcher - path = ^/back - ips = [192.0.0.4] => ][ BasicAuthenticationListener RequestMatcher - path: ^/customer => ][ ContextListener , SimpleFormAuthenticationListener RequestMatcher => ][AnonymousAuthenticationListener Utiliser l’authentification HTTP basic pour toutes les requêtes qui commencent par /back Authentifier les requêtes qui commencent par /customer à l’aide d’un formulaire classique Authentifier toutes les autres requêtes comme anonymes Firewall
  • 15. 15 // public/index.php use SymfonyComponentHttpFoundationRequestMatcher; use SymfonyComponentSecurityHttpFirewall; use SymfonyComponentSecurityHttpFirewallMap; // ... // Create main security listener that handles authentication. $securityListener = new AppSecurityMainSecurityListener($tokenStorage); // Create firewall map and add main security listener under URLs starting with "/main". $firewallMap = new FirewallMap(); $firewallMap->add(new RequestMatcher('^/main'), [$securityListener]); // Create firewall and add it to dispatcher. $firewall = new Firewall($firewallMap, $dispatcher); $dispatcher->addSubscriber($firewall); // ... Firewall attends l’événement REQUEST pour exécuter MainSecurityListener si le path de la requête commence par /main. Firewall
  • 16. 16 use SymfonyComponentHttpKernelEventGetResponseEvent; use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; use SymfonyComponentSecurityHttpFirewallListenerInterface; class MainSecurityListener implements ListenerInterface { /** @var TokenStorageInterface */ private $tokenStorage; public function handle(GetResponseEvent $event) { $request = $event->getRequest(); $user = $request->query->get('auth_user'); $password = $request->query->get('auth_pw'); if ($user === 'vlad' && $password === 'pass') { $token = new UsernamePasswordToken($user, $password, 'main', ['ROLE_USER']); $this->tokenStorage->setToken($token); } } } MainSecurityListener implémente désormais ListenerInterface. Firewall
  • 17. App SymfonyComponentSecurityHttpFirewall anon. 17 Permettre aux utilisateurs de s’authentifier comme des anonymes.Tâche 3 RequestMatcher - path = ^/main => ][ MainSecurityListener AnonymousAuthenticationListener // public/index.php use SymfonyComponentHttpFoundationRequestMatcher; use SymfonyComponentSecurityHttpFirewallMap; use SymfonyComponentSecurityHttpFirewallAnonymousAuthenticationListener; // ... // Create a security listener that adds anonymous token if none is already present. $anonListener = new AnonymousAuthenticationListener($tokenStorage, 'secret'); // Create firewall map and add main security listener under URLs starting with "/main". $firewallMap = new FirewallMap(); $firewallMap->add(new RequestMatcher('^/main'), [$securityListener, $anonListener]);
  • 18. User provider 18 Abstraire le moyen de récupération des utilisateurs et déplacer cette logique en dehors des security listeners.Tâche 4 SymfonyComponentSecurityCoreUser UserProviderInterface + loadUserByUsername($username): UserInterface + refreshUser(UserInterface $user) + supportsClass($class) Security Listener - userProvider + loadUserByUsername($username):User UserInterface + getUsername() + getRoles() + getPassword() + getSalt() + eraseCredentials() + isEnabled() UserInMemoryUserProvider
  • 19. 19 use SymfonyComponentHttpKernelEventGetResponseEvent; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; use SymfonyComponentSecurityCoreExceptionUsernameNotFoundException; use SymfonyComponentSecurityCoreUserUserProviderInterface; use SymfonyComponentSecurityHttpFirewallListenerInterface; class MainSecurityListener implements ListenerInterface { /** @var UserProviderInterface */ private $userProvider; public function handle(GetResponseEvent $event) { $request = $event->getRequest(); $username = $request->query->get('auth_user'); $password = $request->query->get('auth_pw'); try { $user = $this->userProvider->loadUserByUsername($username); if ($user->getPassword() === $password) { $token = new UsernamePasswordToken($user, $password, 'main', $user->getRoles()); $this->tokenStorage->setToken($token); } } catch (UsernameNotFoundException $e) { } } } User provider
  • 20. 20 // public/index.php use SymfonyComponentEventDispatcherEventDispatcher; use SymfonyComponentHttpFoundationRequestMatcher; use SymfonyComponentSecurityHttpFirewallMap; use SymfonyComponentSecurityHttpFirewall; use SymfonyComponentSecurityCoreUserInMemoryUserProvider; // ... // Create user provider that will be used by authentication listener. $mainUserProvider = new InMemoryUserProvider([ 'vlad' => ['password' => 'pass', 'roles' => ['ROLE_USER’]], ]); // Create main security listener that handles authentication. $mainSecurityListener = new AppSecurityMainSecurityListener($tokenStorage, $mainUserProvider); // Create firewall map and add main security listener under URLs starting with "/main". $firewallMap = new FirewallMap(); $firewallMap->add(new RequestMatcher('^/main'), [$mainSecurityListener, $anonListener]); // ... User provider Création d’un user provider pour main security listener.
  • 21. App 21Auth provider Ajouter l’encodage du mot de passe, n’accepter que des utilisateurs activés. Déplacer la logique d’authentification en dehors des security listeners.Tâche 5 - tokenStorage - authenticationManager SymfonyComponentSecurityCoreAuthentication AuthenticationManagerInterface + authenticate(TokenInterface $token) MainSecurityListener ̶ Être rappelé par Firewall pendant l’événement REQUEST ̶ Extraire l’identifiant et le mot de passe ̶ Créer le token non authentifié ̶ Passer le token à l’authentification manager ̶ Mettre le token authentifié dans le token storage ̶ Récupérer l’utilisateur grâce à l’identifiant et à l’aide de user provider ̶ Vérifier le mot de passe à l’aide de password encoder ̶ Vérifier les autres paramètres ̶ Renvoyer le token authentifié $token->setAuthenticated(true) créer un nouveau token
  • 22. SymfonyComponentSecurityCoreAuthentication 22Auth provider Provider DaoAuthenticationProvider - userProvider - encoderFactory - userChecker AuthenticationManagerInterface + authenticate(TokenInterface $token) SymfonyComponentSecurityCoreUser UserProviderInterface + loadUserByUsername($username) + refreshUser(UserInterface $user) + supportsClass($class) + loadUserByUsername($username):User InMemoryUserProvider
  • 23. SymfonyComponentSecurityCoreAuthentication 23Auth provider Provider DaoAuthenticationProvider - userProvider - encoderFactory - userChecker SymfonyComponentSecurityCoreEncoder EncoderFactoryInterface + getEncoder($user): PasswordEncoderInterface PasswordEncoderInterface + encodePassword($raw, $salt) + isPasswordValid($encoded, $raw, $salt) - cost: int BCryptPasswordEncoder - encoders: array EncoderFactory
  • 24. SymfonyComponentSecurityCoreAuthentication 24Auth provider Provider DaoAuthenticationProvider AuthenticationManagerInterface + authenticate(TokenInterface $token) SymfonyComponentSecurityCoreUser UserChecker + checkPreAuth(UserInterface $user) + checkPostAuth(UserInterface $user) UserCheckerInterface - userProvider - encoderFactory - userChecker
  • 25. 25Auth provider use SymfonyComponentSecurityCoreAuthenticationAuthenticationManagerInterface; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; use SymfonyComponentSecurityCoreExceptionAuthenticationException; class MainSecurityListener implements ListenerInterface { /** @var AuthenticationManagerInterface */ private $authenticationManager; public function handle(GetResponseEvent $event) { // Extract authentication credentials. if ($username && $credentials) { try { // Token is not authenticated because no role is passed. $token = new UsernamePasswordToken($username, $credentials, 'main'); // Try to authenticate the token. // If there is an authentication error an AuthenticationException is thrown. $token = $this->authenticationManager->authenticate($token); // Add authenticated token to storage. $this->tokenStorage->setToken($token); } catch (AuthenticationException $e) {} } } }
  • 26. 26Auth provider use SymfonyComponentSecurityCoreAuthenticationProviderDaoAuthenticationProvider; use SymfonyComponentSecurityCoreEncoderBCryptPasswordEncoder; // Create user provider that will be used by authentication listener. $mainUserProvider = new InMemoryUserProvider([ 'vlad' => [ 'password' => '$2y$10$zDUW3BF4T5ZVloDZqp0SN.1Ic4DG3xfxHUDXWkkpvaP0G8qXnq', // encoded 'pass' 'roles' => ['ROLE_USER'], 'enabled' => true ] ]); // And object that checks whether a user is non-locked, enabled, not expired, etc. $mainUserChecker = new SymfonyComponentSecurityCoreUserUserChecker(); // A factory that specifies encoding algorithm to each user class. $encoderFactory = new SymfonyComponentSecurityCoreEncoderEncoderFactory([ SymfonyComponentSecurityCoreUserUser::class => new BCryptPasswordEncoder(10) ]); // Create a provider to which security listener will delegate an authentication. $mainAuthProvider = new DaoAuthenticationProvider( $mainUserProvider, $mainUserChecker, 'main', $encoderFactory ); // Create main security listener that handles authentication. $mainSecurityListener = new AppSecurityMainSecurityListener($tokenStorage, $mainAuthProvider);
  • 27. 27HTTP basic auth Mettre en place l’authentification HTTP, laisser passer seulement les utilisateurs connectés.Tâche 6 SymfonyComponentSecurityHttpFirewall - tokenStorage - authenticationManager BasicAuthenticationListener - tokenStorage - accessDecisionManager AccessListener RequestMatcher - path: ^/main => Extraire l’identifiant et le mot de passe de l'en-tête Authorization. Créer le token, l'authentifier, le sauvegarder dans token storage. Lancer une exception si les credentials ne sont pas valides. Lancer une exception si le token n’est pas présent ou s’il ne respecte pas les règles d’accès.
  • 28. 28 SymfonyComponentSecurityHttpEntryPoint + start(Request $request, $authException): Response AuthenticationEntryPointInterface - realmName: string BasicAuthenticationEntryPoint Lors de l'exception d’authentification (accès anonyme ou identifiants non valides) il faut aider l’utilisateur à (re-)commencer l’authentification. SymfonyComponentSecurityHttpFirewall - tokenStorage - authenticationManager - authenticationEntryPoint BasicAuthenticationListener Event Dispatcher - Kernel::EXCEPTION => [...] - authenticationEntryPoint ExceptionListener HTTP basic auth
  • 29. 29 use SymfonyComponentHttpFoundationRequestMatcher; use SymfonyComponentSecurityHttpAccessMap; use SymfonyComponentSecurityHttpFirewallMap; use SymfonyComponentSecurityHttpFirewallBasicAuthenticationListener; use SymfonyComponentSecurityHttpFirewallAccessListener; use SymfonyComponentSecurityHttpEntryPointBasicAuthenticationEntryPoint; use SymfonyComponentSecurityCoreAuthorizationAccessDecisionManager; // Entry point helps user to authenticate. $basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint('Secured area'); // Create HTTP basic security listener that extracts credentials from headers (RFC 7617). $mainSecurityListener = new BasicAuthenticationListener( $tokenStorage, $mainAuthProvider, 'main', $basicAuthenticationEntryPoint ); // Access listener will throw an exception when no token is already present. $accessDecisionManager = new AccessDecisionManager(); $accessMap = new AccessMap(); $accessListener = new AccessListener( $tokenStorage, $accessDecisionManager, $accessMap, $mainAuthProvider ); // Create firewall map and add main security listener under URLs starting with "/main". $firewallMap = new FirewallMap(); $firewallMap->add(new RequestMatcher('^/main'), [$mainSecurityListener, $accessListener]); // ... HTTP basic auth
  • 30. 30 use SymfonyComponentSecurityHttpHttpUtils; use SymfonyComponentSecurityCoreAuthenticationAuthenticationTrustResolver; use SymfonyComponentSecurityCoreAuthenticationTokenAnonymousToken; use SymfonyComponentSecurityCoreAuthenticationTokenRememberMeToken; use SymfonyComponentHttpKernelKernelEvents; // ... // ExceptionListener catches authentication exception and converts them to Response instance. // In this case it invites user to enter its credentials by returning 401 response. $authTrustResolver = new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class); $httpUtils = new HttpUtils(); $exceptionListener = new ExceptionListener( $tokenStorage, $authTrustResolver, $httpUtils, 'main', $basicAuthenticationEntryPoint ); $dispatcher->addListener(KernelEvents::EXCEPTION, array($exceptionListener, 'onKernelException'), 1); // ... HTTP basic auth
  • 31. 31Formulaire de connexion Mettre en place l’authentification par le formulaire de connexion pour une autre partie de site.Tâche 7 SymfonyComponentSecurityHttpFirewall - tokenStorage - userProviders ContextListener - tokenStorage - accessDecisionManager - options - successHandler - failureHandler UsernamePasswordFormAuthenticationListener RequestMatcher - path: ^/front => + handle(GetResponseEvent $event) + onKernelResponse(FilterResponseEvent $event) + handle(GetResponseEvent $event) Récupérer le token d’une session lors de l’événement REQUEST. Sauvegarder le token dans une session lors de l’événement RESPONSE. Authentifier l’utilisateur seulement quand le formulaire de connexion est envoyé (POST sur /front/login_check).
  • 32. 32Formulaire de connexion use SymfonyComponentHttpFoundationResponse; class Controller { public function loginFormAction() { return new Response(<<<END <form action="/front/login_check" method="POST"> <input type="text" name="_username" placeholder="username"> <input type="password" name="_password" placeholder="password"> <input type="submit"> </form> END ); } public function defaultAction() { $token = $this->tokenStorage->getToken(); $user = $token ? $token->getUser() : null; // ... } } Nouvelle action pour visualiser le formulaire de conexion : POST sur /front/login_check.
  • 33. 33Formulaire de connexion use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpKernelControllerControllerResolverInterface; class ControllerResolver implements ControllerResolverInterface { /** @var callable[] */ private $routes; /** @var callable */ private $default; public function getController(Request $request) { foreach ($this->routes as $pattern => $controller) { if (preg_match($pattern, $request->getPathInfo())) { return $controller; } } return $this->default; } } La nouvelle action sera appelée quand la requête est faite sur /font/login.
  • 34. 34Formulaire de connexion // public/index.php use SymfonyComponentEventDispatcherEventDispatcher; use SymfonyComponentHttpKernelHttpKernel; // ... // Controller creates a response to send to the user. $controller = new AppController($request, $tokenStorage); $controllerResolver = new AppControllerResolver( ['/^/front/login$/' => [$controller, 'loginFormAction']], [$controller, 'defaultAction'] ); // Kernel is in charge of converting a Request into a Response by using the event dispatcher. $kernel = new HttpKernel($dispatcher, $controllerResolver); // ... La nouvelle action sera appelée quand la requête est faite sur /font/login.
  • 35. 35Formulaire de connexion // public/index.php use SymfonyComponentSecurityHttpFirewallContextListener; // ... // ContextListener retrieves previously authenticated token from the session during REQUEST event. // It also saves token during RESPONSE event. $contextListener = new ContextListener( $tokenStorage, [$mainUserProvider], 'front', null, $dispatcher ); // ... Context security listener :
  • 36. 36Formulaire de connexion use SymfonyComponentSecurityHttpAuthenticationDefaultAuthenticationSuccessHandler; use SymfonyComponentSecurityHttpAuthentication DefaultAuthenticationFailureHandler; use SymfonyComponentSecurityHttpFirewallUsernamePasswordFormAuthenticationListener; use SymfonyComponentSecurityHttpSessionSessionAuthenticationStrategy; $sessionAuthenticationStrategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE); $successHandler = new DefaultAuthenticationSuccessHandler( $httpUtils, ['default_target_path' => '/front/success’] ); $failureHandler = new DefaultAuthenticationFailureHandler( $kernel, $httpUtils, ['login_path' => '/front/login’] ); // Listens for login form being send (POST to '/front/login_check'). // It extracts credentials, creates token, authenticates it and puts it to the token storage. $formAuthListener = new UsernamePasswordFormAuthenticationListener( $tokenStorage, $frontAuthProvider, $sessionAuthenticationStrategy, $httpUtils, 'front', $successHandler, // Redirect user to '/front/success' if credentials are valid $failureHandler, // Redirect user to '/front/login' if credentials are invalid ['check_path' => '/front/login_check’, 'post_only' => true] // Act only on POST to '/front/login_check' );
  • 37. 37Formulaire de connexion // public/index.php use SymfonyComponentHttpFoundationRequestMatcher; use SymfonyComponentSecurityHttpFirewallMap; // ... $firewallMap = new FirewallMap(); $firewallMap->add(new RequestMatcher('^/main'), [$mainSecurityListener, $accessListener]); $firewallMap->add(new RequestMatcher('^/front'), [$contextListener, $formAuthListener]); // ... Ajout de security listeners dans le Firewall :
  • 38. Merci pour votre attention Le code de cette présentation : https://github.com/vria/symfony-security-component-use