Slide 1

Slide 1 text

IMPLEMENT SINGLE SIGN ON EASILY WITH SYMFONY Sarah Khalil - @saro0h

Slide 2

Slide 2 text

IMPLEMENT SINGLE SIGN ON EASILY WITH SYMFONY Sarah Khalil - @saro0h Disclaimer you need to have some experience with security in Symfony.

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

WHAT’S THE PLAN? 1. Security in Symfony 2. Let’s implement authentication with Github (without any third party library) 3. Authenticate apps in the SOA context 4. Advices

Slide 6

Slide 6 text

I. SECURITY IN SYMFONY

Slide 7

Slide 7 text

Security Component

Slide 8

Slide 8 text

Security Bundle

Slide 9

Slide 9 text

2 MAIN PARTS •Authentication •Authorization We won’t talk about that today. OK, just a little.

Slide 10

Slide 10 text

LET’S TALK ABOUT AUTHENTICATION

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

WHAT DO WE HAVE TO WRITE? Most of the time, it’s all about configuration.

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 that 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 | /admin/myprofile or

Slide 77

Slide 77 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 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

WHAT DO WE HAVE MORE? Authorization

Slide 81

Slide 81 text

SERVICES No more security.context!

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 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 86

Slide 86 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 87

Slide 87 text

II. AUTHENTICATION WITH GITHUB

Slide 88

Slide 88 text

VERY FIRST STEPS • http://symfony.com/doc/current/cookbook/security/ api_key_authentication.html • https://developer.github.com/v3/oauth/ • https://github.com/settings/applications/new • https://github.com/csarrazi/CsaGuzzleBundle • [supports last version of Guzzle]

Slide 89

Slide 89 text

OAUTH • Protocol • 2 versions • Read the documentation of the service you need to use

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

IMPLEMENTATION

Slide 94

Slide 94 text

CREATE THE USER CLASS Stores all information coming from the provider.

Slide 95

Slide 95 text

CREATE THE TEMPLATES

Slide 96

Slide 96 text

CREATE THE TEMPLATES {% extends 'base.html.twig' %} {% block body %}

Homepage !

This application shows how to implement an authentication with Github with Symfony.

{% endblock %} {% extends 'base.html.twig' %} {% block body %}

Administration

If you can access this page, it's because you are authenticated.

Actually you are!
Your login: {{ app.user.username }}
Your name (in case you forgot…): {{ app.user.name }}
Aaaaand your email address: {{ app.user.email }}
Your FACE: {% endblock %} admin.html.twig index.html.twig

Slide 97

Slide 97 text

CONFIGURE THE SecurityBundle

Slide 98

Slide 98 text

No content

Slide 99

Slide 99 text

security: firewalls: secured_area: pattern: ^/admin stateless: false simple_preauth: authenticator: github_authenticator provider: github_user_provider logout: path: /admin/logout target: /

Slide 100

Slide 100 text

security: firewalls: secured_area: pattern: ^/admin stateless: false simple_preauth: authenticator: github_authenticator provider: github_user_provider logout: path: /admin/logout target: / Trigger authentication!

Slide 101

Slide 101 text

security: firewalls: secured_area: pattern: ^/admin stateless: false simple_preauth: authenticator: github_authenticator provider: github_user_provider logout: path: /admin/logout target: / Create that authenticator Trigger authentication!

Slide 102

Slide 102 text

security: firewalls: secured_area: pattern: ^/admin stateless: false simple_preauth: authenticator: github_authenticator provider: github_user_provider logout: path: /admin/logout target: / Create that authenticator Create that provider Trigger authentication!

Slide 103

Slide 103 text

AUTHENTICATOR

Slide 104

Slide 104 text

class GithubAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface { public function createToken(Request $request, $providerKey) { // This method is called first. // Get an access token to be able to use the API of Github // return a PreAuthenticatedToken storing this access token. No user yet! } public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) { // This method is called secondly. // Call the loadUserByUsername from the provider, responsible of getting the user through the API thanks to the access token // return a PreAuthenticatedToken storing the user and its roles. } public function supportsToken(TokenInterface $token, $providerKey) { // Make sure that the token is an instance of PreAuthenticatedToken // and that it stores the provider key } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { return new Response("Authentication Failed :(", 401); } }

Slide 105

Slide 105 text

Make it a service. id => github_authenticator

Slide 106

Slide 106 text

PROVIDER

Slide 107

Slide 107 text

security: firewalls: #… providers: github_user_provider: id: github_user_provider

Slide 108

Slide 108 text

class GithubUserProvider implements UserProviderInterface { public function loadUserByUsername($username) { // Calls the Github API to get the user info. // Creates the User object with all of the info. } public function refreshUser(UserInterface $user) { // Called at each request. // Returns the object user coming from the session. } public function supportsClass($class) { return 'AppBundle\Model\User' === $class; } }

Slide 109

Slide 109 text

Make it a service. id => github_user_provider

Slide 110

Slide 110 text

No content

Slide 111

Slide 111 text

No content

Slide 112

Slide 112 text

III. AUTHENTICATE WITH ALL APPS

Slide 113

Slide 113 text

OAuth server app 1 app 2 app 3 app n

Slide 114

Slide 114 text

OAuth server ecommerce API Blog API Frontend Backend

Slide 115

Slide 115 text

OAuth server ecommerce API Blog API Frontend Backend http://e-commerce.api.domain.name/ http://blog.api.domain.name/ http://domain.name/ http://domain.name/

Slide 116

Slide 116 text

• UserAPI • Contacts the Oauth server; • Is your own Oauth server; • Authenticates each request. • Each app must have its OAUTH application credentials registered to have the right settings for each micro service.

Slide 117

Slide 117 text

OAuth server Frontend blog API

Slide 118

Slide 118 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me

Slide 119

Slide 119 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me

Slide 120

Slide 120 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate

Slide 121

Slide 121 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate returns access token

Slide 122

Slide 122 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate returns access token with access token

Slide 123

Slide 123 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate returns access token validate access token with access token

Slide 124

Slide 124 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate returns access token validate access token validated with access token

Slide 125

Slide 125 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate returns access token validate access token validated get articles with access token

Slide 126

Slide 126 text

OAuth server Frontend blog API http://domain.name/articles http://api-blog.domain.name/articles http://api-user.domain.name/me authenticate returns access token validate access token validated get articles with access token

Slide 127

Slide 127 text

EXCHANGE TOKEN BETWEEN APPLICATIONS

Slide 128

Slide 128 text

Front 1 Front 2 GET / HTTP/1.1 Host: backend.domain.name Authorization: bearer xxxx-xxxx GET /#xxxx-xxxx HTTP/1.1 Host: domain.name

Slide 129

Slide 129 text

Front 1 Front 2 GET / HTTP/1.1 Host: backend.domain.name Authorization: bearer xxxx-xxxx GET /#xxxx-xxxx HTTP/1.1 Host: domain.name Event[Listener|Subscriber] => kernel.request to extract the token: 1. Validate the token; 2. Call the API to get the user info from the Oauth server; 3. User authenticated.

Slide 130

Slide 130 text

Front 1 Front 2 GET / HTTP/1.1 Host: backend.domain.name Authorization: bearer xxxx-xxxx GET /#xxxx-xxxx HTTP/1.1 Host: domain.name Event[Listener|Subscriber] => kernel.request to extract the token: 1. Validate the token; 2. Call the API to get the user info from the Oauth server; 3. User authenticated. Is he/she? For Symfony, nope.

Slide 131

Slide 131 text

Front 1 Front 2 GET / HTTP/1.1 Host: backend.domain.name Authorization: bearer xxxx-xxxx GET /#xxxx-xxxx HTTP/1.1 Host: domain.name

Slide 132

Slide 132 text

Front 1 Front 2 GET / HTTP/1.1 Host: backend.domain.name Authorization: bearer xxxx-xxxx GET /#xxxx-xxxx HTTP/1.1 Host: domain.name In the application you are redirecting your user, make sure that the firewall triggers authentication when the user comes from another application (another firewall for another pattern for instance). And in your authenticator extract the access token from your header/URI to finally do your business with the Oauth server to get the user’s info.

Slide 133

Slide 133 text

Front 1 Front 2 GET / HTTP/1.1 Host: backend.domain.name Authorization: bearer xxxx-xxxx GET /#xxxx-xxxx HTTP/1.1 Host: domain.name In the application you are redirecting your user, make sure that the firewall triggers authentication when the user comes from another application (another firewall for another pattern for instance). And in your authenticator extract the access token from your header/URI to finally do your business with the Oauth server to get the user’s info. Now you’re using the security process of Symfony.

Slide 134

Slide 134 text

IF MULTIPLE FRONTENDS • Send the access token from fronts to fronts. • Use: • either the « # » as it is not logged anywhere • and / or the access token in the header. • Use a special listener to get it and have it in the request

Slide 135

Slide 135 text

IV. ADVICES

Slide 136

Slide 136 text

• To mutualise the code to access to the Oauth server • Authenticator, Provider and User class can be in a shared bundle. • To avoid to much connections to the Oauth server (performances) • Cache strategy!

Slide 137

Slide 137 text

No content

Slide 138

Slide 138 text

CACHE STRATEGY In the micro service in charge of the authentication : • When getting back the access token, from the URL or the header • check that the Doctrine cache has the access token and until when the token is valid; • if not: • call the Oauth server, get a new access token; • save the access token, when it expires and the user info.

Slide 139

Slide 139 text

CACHE STRATEGY Store those tokens anywhere you want: Redis, MongoDB… Be careful: once logout, the access token needs to be revoked everywhere.

Slide 140

Slide 140 text

No content

Slide 141

Slide 141 text

No content

Slide 142

Slide 142 text

Need training? Come see us at the SensioLabs booth!

Slide 143

Slide 143 text

Thank you! @saro0h speakerdeck.com/saro0h/ saro0h This is a zero guys! github.com/saro0h/oauth-github