Slide 1

Slide 1 text

SECURITY WITH SYMFONY Sarah Khalil - @saro0h @catlannister SfPot Paris - juillet 2015

Slide 2

Slide 2 text

WHO AM I? • Head of • Trainer & Developer • Enjoying sharer

Slide 3

Slide 3 text

WHAT’S THE PLAN? 1. Security in Symfony: Authentication + Authorization 2. Brand new: Guard

Slide 4

Slide 4 text

I. SECURITY IN SYMFONY

Slide 5

Slide 5 text

Security Component

Slide 6

Slide 6 text

Security Bundle

Slide 7

Slide 7 text

2 MAIN PARTS •Authentication •Authorization

Slide 8

Slide 8 text

A. LET’S TALK ABOUT AUTHENTICATION

Slide 9

Slide 9 text

AUTHENTICATION Ensures that the user is who he claims to be.

Slide 10

Slide 10 text

WHAT IS A USER? The object stores: • credentials • associated roles

Slide 11

Slide 11 text

WHAT IS A USER? Symfony\Component\Security\Core\User\UserInterface Symfony\Component\Security\Core\User\AdvancedUserInterface

Slide 12

Slide 12 text

GIMME THAT AUTHENTICATION THING Security = configuration. (most of the time)

Slide 13

Slide 13 text

WHAT DO WE HAVE TO WRITE?

Slide 14

Slide 14 text

WHAT DO WE HAVE TO WRITE? security: encoders: Symfony\Component\Security\Core\User\User: bcrypt providers: in_memory: memory: users: sarah: password: $2a$12$LCY0M… roles: 'ROLE_USER' firewalls: admin: provider: in_memory pattern: /^admin form_login: login_path: /login check_path: /login_check

Slide 15

Slide 15 text

WHAT DO WE HAVE TO WRITE? security: encoders: Symfony\Component\Security\Core\User\User: bcrypt providers: in_memory: memory: users: sarah: password: $2a$12$LCY0M… roles: 'ROLE_USER' firewalls: admin: provider: in_memory pattern: /^admin form_login: login_path: /login check_path: /login_check

Slide 16

Slide 16 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder $encoder-­‐>isPasswordValid('mypwd'); Encoder true authenticated false | 401: Unauthorized /admin/myprofile or

Slide 17

Slide 17 text

CONFIGURATION • Firewall • Encoder • Provider

Slide 18

Slide 18 text

FIREWALL

Slide 19

Slide 19 text

Determines whether or not the user needs to be authenticated. AUTHENTICATION: FIREWALL

Slide 20

Slide 20 text

Your application

Slide 21

Slide 21 text

Your application all routes beginning with /shop

Slide 22

Slide 22 text

Your application all routes begin with /admin all routes beginning with /shop

Slide 23

Slide 23 text

Your application all routes begin with /admin all routes beginning with /shop all routes beginning with /blog

Slide 24

Slide 24 text

Your application all routes begin with /admin all routes beginning with /shop all routes beginning with /blog all other routes…

Slide 25

Slide 25 text

Your application all routes begin with /admin all routes beginning with /shop all routes beginning with /blog all other routes… The user needs to be authenticated to access this part of the app

Slide 26

Slide 26 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ authenticated 401: Unauthorized or /admin/myprofile

Slide 27

Slide 27 text

WHAT DO WE HAVE TO WRITE? security: firewalls: admin: provider: in_memory pattern: /^admin form_login: login_path: /login check_path: /login_check

Slide 28

Slide 28 text

BUILT-IN WAYS OF AUTHENTICATING A USER

Slide 29

Slide 29 text

http-basic http-digest BUILT-IN WAYS OF AUTHENTICATING A USER

Slide 30

Slide 30 text

http-basic http-digest form-based BUILT-IN WAYS OF AUTHENTICATING A USER

Slide 31

Slide 31 text

http-basic http-digest form-based x.509 certificate BUILT-IN WAYS OF AUTHENTICATING A USER

Slide 32

Slide 32 text

PROVIDER

Slide 33

Slide 33 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 34

Slide 34 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 35

Slide 35 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 36

Slide 36 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 37

Slide 37 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 38

Slide 38 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 39

Slide 39 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 40

Slide 40 text

Finds and/or creates users AUTHENTICATION: PROVIDER

Slide 41

Slide 41 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider authenticated 401: Unauthorized /admin/myprofile or

Slide 42

Slide 42 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); authenticated 401: Unauthorized /admin/myprofile or

Slide 43

Slide 43 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); authenticated 401: Unauthorized /admin/myprofile or

Slide 44

Slide 44 text

security: providers: in_memory: memory: users: sarah: password: $2a$12$LCY0M… roles: 'ROLE_USER'

Slide 45

Slide 45 text

interface UserProviderInterface { /** * Loads the user for the given username. * * This method must throw UsernameNotFoundException if the user is not * found. */ public function loadUserByUsername($username); /** * Refreshes the user for the account interface. * * It is up to the implementation to decide if the user data should be * totally reloaded (e.g. from the database), or if the UserInterface * object can just be merged into some internal array of users / identity * map. */ public function refreshUser(UserInterface $user); /** * Whether this provider supports the given user class. */ public function supportsClass($class); }

Slide 46

Slide 46 text

ENCODER

Slide 47

Slide 47 text

AUTHENTICATION: ENCODER Used for hashing and comparing a password.

Slide 48

Slide 48 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ authenticated Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 49

Slide 49 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory authenticated Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 50

Slide 50 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory $factory-­‐>getEncoder($user); authenticated Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 51

Slide 51 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory $factory-­‐>getEncoder($user); $encoder authenticated Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 52

Slide 52 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder authenticated Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 53

Slide 53 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); authenticated Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 54

Slide 54 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); authenticated true Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 55

Slide 55 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); authenticated true Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile false | 401: Unauthorized or

Slide 56

Slide 56 text

CONFIGURATION security: encoders: Symfony\Component\Security\Core\User\User: bcrypt SecurityBundle

Slide 57

Slide 57 text

interface PasswordEncoderInterface { /** * Encodes the raw password. */ public function encodePassword($raw, $salt); /** * Checks a raw password against an encoded password. */ public function isPasswordValid($encoded, $raw, $salt); }

Slide 58

Slide 58 text

ALL TOGETHER NOW!

Slide 59

Slide 59 text

security: encoders: Symfony\Component\Security\Core\User\User: bcrypt providers: in_memory: memory: users: sarah: password: $2a$12$LCY0M… roles: 'ROLE_USER' firewalls: admin: provider: in_memory pattern: /^admin form_login: login_path: /login check_path: /login_check

Slide 60

Slide 60 text

AUTHENTICATION FLOW backend

Slide 61

Slide 61 text

AUTHENTICATION FLOW backend /admin/myprofile

Slide 62

Slide 62 text

AUTHENTICATION FLOW Firewall backend /admin/myprofile

Slide 63

Slide 63 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ /admin/myprofile

Slide 64

Slide 64 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ /admin/myprofile

Slide 65

Slide 65 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider /admin/myprofile

Slide 66

Slide 66 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); /admin/myprofile

Slide 67

Slide 67 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); /admin/myprofile

Slide 68

Slide 68 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory /admin/myprofile

Slide 69

Slide 69 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); /admin/myprofile

Slide 70

Slide 70 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder /admin/myprofile

Slide 71

Slide 71 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder /admin/myprofile

Slide 72

Slide 72 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); /admin/myprofile

Slide 73

Slide 73 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); true /admin/myprofile

Slide 74

Slide 74 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); true authenticated /admin/myprofile

Slide 75

Slide 75 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); true authenticated /admin/myprofile or

Slide 76

Slide 76 text

AUTHENTICATION FLOW Firewall backend username = ‘sarah.khalil’ password = ‘mypwd’ Provider $provider-­‐>loadUserByUsername('sarah.khalil'); $user  =  new  User(‘sarah.khalil’); Encoder Factory $factory-­‐>getEncoder($user); $encoder Encoder $encoder-­‐>isPasswordValid('mypwd'); true authenticated false | 401: Unauthorized /admin/myprofile or

Slide 77

Slide 77 text

B. AUTHORIZATION

Slide 78

Slide 78 text

BEFORE GETTING ANY FURTHER No more security.context!

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

$this->get('security.context')->getToken()->getUser(); Before 2.6

Slide 81

Slide 81 text

After $this->get('security.token_storage')->getToken()->getUser(); $this->get('security.context')->getToken()->getUser(); Before 2.6

Slide 82

Slide 82 text

After $this->get('security.token_storage')->getToken()->getUser(); $this->get('security.context')->getToken()->getUser(); Before 2.6 Before 2.6 $this->get('security.context')->isGranted(‘ROLE_USER’);

Slide 83

Slide 83 text

After $this->get('security.token_storage')->getToken()->getUser(); $this->get('security.context')->getToken()->getUser(); Before 2.6 Before 2.6 $this->get('security.context')->isGranted(‘ROLE_USER’); After $this->get('security.authorization_checker')->isGranted(‘ROLE_USER’);

Slide 84

Slide 84 text

OK, back to business.

Slide 85

Slide 85 text

$this-­‐>denyAccessUnlessGranted('ROLE_ADMIN',  null,  'Unable  to  access  this  page!');   $decision  =  $this-­‐>get('security.authorization_checker')-­‐>isGranted('ROLE_ADMIN');   if  (false  ===  $decision)  {          throw  $this-­‐>createAccessDeniedException('Unable  to  access  this  page!');   } What you have usually in a controller or

Slide 86

Slide 86 text

Or in a template {%  if  is_granted('ROLE_ADMIN')  %}          Delete   {%  endif  %}

Slide 87

Slide 87 text

Or in a template {%  if  is_granted('ROLE_ADMIN')  %}          Delete   {%  endif  %} Symfony\Bridge\Twig\Extension\SecurityExtension

Slide 88

Slide 88 text

HOW DOES IT WORKS?

Slide 89

Slide 89 text

Let’s take a look at the security.authorization_chec ker service.

Slide 90

Slide 90 text

       final  public  function  isGranted($attributes,  $object  =  null)          {                  //  Checks  if  there  is  someone  authenticated  (if  there  is  a  token)   //  Makes  sure  that  the  attributes  in  an  array   //  returns  true  or  false                  return  $this-­‐>accessDecisionManager-­‐>decide($token,  $attributes,  $object);          } Symfony\Component\Security\Core\Authorization \AccessDecisionManagerInterface Any string that represent a permission anything that can help to make a decision

Slide 91

Slide 91 text

Symfony\Component\Security\Core\Authorization \AccessDecisionManager The object needs: • voters • a strategy • $allowIfAllAbstainDecisions • $allowIfEqualGrantedDeniedDecisions

Slide 92

Slide 92 text

VOTERS Voters are added in a compiler pass (Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass ) The services must have a « security.voter » tag to be added in the AccessDecisionManager.

Slide 93

Slide 93 text

VOTERS Voters are added in a compiler pass (Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass ) The services must have a « security.voter » tag to be added in the AccessDecisionManager. All the voters are sorted by the attribute priority (the higher one is the last to be executed). If you don’t put any priority, => 0 (first to be executed) Why? To make sure that is doesn’t mess with other decisions taken

Slide 94

Slide 94 text

$strategy, $allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions //  Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension   $container          -­‐>getDefinition('security.access.decision_manager')          -­‐>addArgument($config['access_decision_manager']['strategy'])          -­‐>addArgument(                    $config['access_decision_manager']['allow_if_all_abstain']          )          -­‐>addArgument(                    $config['access_decision_manager']['allow_if_equal_granted_denied']          )   ;

Slide 95

Slide 95 text

$strategy  =   $allowIfAllAbstainDecisions  =   $allowIfEqualGrantedDeniedDecisions  =  true affirmative or consensus or unanimous true or false true or false

Slide 96

Slide 96 text

$strategy  =  affirmative   $allowIfAllAbstainDecisions  =  false   $allowIfEqualGrantedDeniedDecisions  =  true Default values

Slide 97

Slide 97 text

Symfony\Component\Security\Core\Authorization \AccessDecisionManager The object needs: • voters • a strategy • $allowIfAllAbstainDecisions • $allowIfEqualGrantedDeniedDecisions

Slide 98

Slide 98 text

//Symfony\Component\Security\Core\Authorization\AccessDecisionManager   public  function  decide(TokenInterface  $token,  array  $attributes,  $object  =  null)   {            return   $this-­‐>{$this-­‐>strategy} ($token,  $attributes,  $object);   } decideAffirmative decideConsensus decideUnanimous

Slide 99

Slide 99 text

decideAffirmative • Donne accès si n’importe lequel des voter dit ACCES_GRANTED. • Si tous les voters disent ACCES_ABSTAIN => $allowIfAllAbstainDecision prend la décision. One says yes. default = false

Slide 100

Slide 100 text

decideConsensus • Donne accès si la majorité (sans les abstentions) dit ACCES_GRANTED. • S’il y a autant de ACCES_GRANTED que d’ ACCES_DENIED => $allowIfEqualGrantedDeniedDecision prend la décision • Si tous les voters disent ACCES_ABSTAIN => $allowIfAllAbstainDecision prend la décision. Most of them says yes. default = true

Slide 101

Slide 101 text

decideUnanimous • Donne accès si tous les voters (sans les abstentions) disent ACCES_GRANTED. • Si tous les voters disent ACCES_ABSTAIN => $allowIfAllAbstainDecision prend la décision. All of them says yes. default = false

Slide 102

Slide 102 text

decideXxxx //Symfony\Component\Security\Core\Authorization\AccessDecisionManager   //…   foreach  ($this-­‐>voters  as  $voter)  {          $result  =  $voter-­‐>vote($token,  $object,  $attributes);   }   //  logic  to  return  true  or  false   200 or 403 (forbidden)

Slide 103

Slide 103 text

Voter MUST NOT be called by you. Voter = Private Service

Slide 104

Slide 104 text

Voter MUST NOT be called by you. Voter = Private Service

Slide 105

Slide 105 text

ALL TOGETHER NOW!

Slide 106

Slide 106 text

AuthorizationChecker::isGranted()

Slide 107

Slide 107 text

Controller or template or service from AuthorizationChecker::isGranted()

Slide 108

Slide 108 text

Controller or template or service from AuthorizationChecker::isGranted() AccessDecisionManager::decide()

Slide 109

Slide 109 text

Controller or template or service from AuthorizationChecker::isGranted() Strategy Voters Decision maker if all can’t make a decision Decision maker if all abstain needs AccessDecisionManager::decide()

Slide 110

Slide 110 text

Controller or template or service from AuthorizationChecker::isGranted() AccessDecisionManager::decideAffirmative() or AccessDecisionManager::decideConsensus() or AccessDecisionManager::decideUnanimous() Strategy Voters Decision maker if all can’t make a decision Decision maker if all abstain needs AccessDecisionManager::decide()

Slide 111

Slide 111 text

Controller or template or service from VoterInterface::vote() … VoterInterface::vote() calls AuthorizationChecker::isGranted() AccessDecisionManager::decideAffirmative() or AccessDecisionManager::decideConsensus() or AccessDecisionManager::decideUnanimous() Strategy Voters Decision maker if all can’t make a decision Decision maker if all abstain needs AccessDecisionManager::decide()

Slide 112

Slide 112 text

Controller or template or service from VoterInterface::vote() … VoterInterface::vote() calls AuthorizationChecker::isGranted() AccessDecisionManager::decideAffirmative() or AccessDecisionManager::decideConsensus() or AccessDecisionManager::decideUnanimous() false true returns Strategy Voters Decision maker if all can’t make a decision Decision maker if all abstain needs AccessDecisionManager::decide()

Slide 113

Slide 113 text

II. BRAND NEW

Slide 114

Slide 114 text

II. BRAND NEW

Slide 115

Slide 115 text

No content

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

No content

Slide 118

Slide 118 text

Previously… with the SimplePreauthenticator (1/4) • Implement the SimplePreAuthenticatorInterface: 1.createToken(Request $request, $providerKey) 2.authenticateToken(TokenInterface $token, UserProviderInterface $userProvider) 3.supportsToken(TokenInterface $token, $provider)

Slide 119

Slide 119 text

Previously… with the SimplePreauthenticator (1/4) • Implement the SimplePreAuthenticatorInterface: 1.createToken(Request $request, $providerKey) 2.authenticateToken(TokenInterface $token, UserProviderInterface $userProvider) 3.supportsToken(TokenInterface $token, $provider) declare it as a service (github_authenticator)

Slide 120

Slide 120 text

Previously… with the SimplePreauthenticator (2/4) • Implement the UserProviderInterface: 1.loadUserByUsername($username) 2.refreshUser(UserInterface $user) 3.supportsToken($class)

Slide 121

Slide 121 text

Previously… with the SimplePreauthenticator (2/4) • Implement the UserProviderInterface: 1.loadUserByUsername($username) 2.refreshUser(UserInterface $user) 3.supportsToken($class) declare it as a service (github_authenticator)

Slide 122

Slide 122 text

Previously… with the SimplePreauthenticator (3/4) security: firewalls: #… providers: github_user_provider: id: github_user_provider

Slide 123

Slide 123 text

Previously… with the SimplePreauthenticator (4/4) security: firewalls: secured_area: pattern: ^/admin stateless: false simple_preauth: authenticator: github_authenticator provider: github_user_provider logout: path: /admin/logout target: /

Slide 124

Slide 124 text

No content

Slide 125

Slide 125 text

No content

Slide 126

Slide 126 text

No content

Slide 127

Slide 127 text

Implement the GuardAuthenticatorInterface 1.start(Request $request, AuthenticationException $exception) 2.getCredentials(Request $request) 3.getUser($credentials, UserProviderInterface $userProvider) 4.checkCredentials($credentials, UserInterface $user) 5.onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) 6.onAuthenticationFailure(Request $request, AuthenticationException $exception) 7.supportsRememberMe()

Slide 128

Slide 128 text

LINKS TO REVIEW • http://knpuniversity.com/blog/guard-authentication • https://knpuniversity.com/screencast/guard/api-token#play • https://github.com/knpuniversity/KnpUGuard/tree/master/ src • https://github.com/knpuniversity/KnpUGuardBundle • https://github.com/symfony/symfony/pull/14673

Slide 129

Slide 129 text

• When to create a firewall (different way of authenticating) • Voters must be light in case of unanimous or consensus (because of the fact that all voters are executed)

Slide 130

Slide 130 text

Thank you! @saro0h speakerdeck.com/saro0h/ saro0h github.com/saro0h/oauth-github