@@ -20,7 +20,7 @@ allows you to implement such a scheme really easily.
2020
2121Your exact situation may differ, but in this example, a token is read
2222from an ``apikey `` query parameter, the proper username is loaded from that
23- value, and then a User object is created::
23+ value and then a User object is created::
2424
2525 // src/Acme/HelloBundle/Security/ApiKeyAuthenticator.php
2626 namespace Acme\HelloBundle\Security;
@@ -59,7 +59,9 @@ value, and then a User object is created::
5959 public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
6060 {
6161 $apiKey = $token->getCredentials();
62- if (!$username = $this->userProvider->getUsernameForApiKey($apiKey)) {
62+ $username = $this->userProvider->getUsernameForApiKey($apiKey)
63+
64+ if (!$username) {
6365 throw new AuthenticationException(
6466 sprintf('API Key "%s" does not exist.', $apiKey)
6567 );
@@ -91,10 +93,10 @@ probably differ:
91931. createToken
9294~~~~~~~~~~~~~~
9395
94- Early in the request cycle, Symfony calls ``createToken ``. Your job here
96+ Early in the request cycle, Symfony calls ``createToken() ``. Your job here
9597is to create a token object that contains all of the information from the
9698request that you need to authenticate the user (e.g. the ``apikey `` query
97- parameter). If that information is missing, throwingthe
99+ parameter). If that information is missing, throwinga
98100:class: `Symfony\\ Component\\ Security\\ Core\\ Exception\\ BadCredentialsException `
99101will cause authentication to fail.
100102
@@ -106,11 +108,11 @@ will cause authentication to fail.
1061083. authenticateToken
107109~~~~~~~~~~~~~~~~~~~~
108110
109- If ``supportsToken `` returns ``true ``, Symfony will now call ``authenticateToken ``.
111+ If ``supportsToken() `` returns ``true ``, Symfony will now call ``authenticateToken() ``.
110112One key part is the ``$userProvider ``, which is an external class that helps
111113you load information about the user. You'll learn more about this next.
112114
113- In this specific example, the following things happen in ``authenticateToken ``:
115+ In this specific example, the following things happen in ``authenticateToken() ``:
114116
115117#. First, you use the ``$userProvider `` to somehow look up the ``$username `` that
116118 corresponds to the ``$apiKey ``;
@@ -119,18 +121,18 @@ In this specific example, the following things happen in ``authenticateToken``:
119121#. Finally, you create an *authenticated token * (i.e. a token with at least one
120122 role) that has the proper roles and the User object attached to it.
121123
122- The goal is ultimately to use the ``$apiKey `` to find or create a User object.
123- *How * you do this (e.g. query a database) and the exact class for your User
124- object may vary. Those differences will be most obvious in your user provider.
124+ The goal is ultimately to use the ``$apiKey `` to find or create a ``User ``
125+ object. *How * you do this (e.g. query a database) and the exact class for
126+ your ``User `` object may vary. Those differences will be most obvious in your
127+ user provider.
125128
126129The User Provider
127130~~~~~~~~~~~~~~~~~
128131
129- The ``$userProvider `` can be any user provider (see
130- :doc: `how to create a custom user provider </cookbook/security/custom_provider >`).
132+ The ``$userProvider `` can be any user provider (see:doc: `/cookbook/security/custom_provider `).
131133In this example, the ``$apiKey `` is used to somehow find the username for
132- the user. This work is done in a ``getUsernameForApiKey `` method, which is
133- created entirely custom forour use-case (i.e. this isn't a method that's
134+ the user. This work is done in a ``getUsernameForApiKey() `` method, which
135+ is created entirely custom forthis use-case (i.e. this isn't a method that's
134136used by Symfony's core user provider system).
135137
136138The ``$userProvider `` might look something like this::
@@ -140,14 +142,16 @@ The ``$userProvider`` might look something like this::
140142
141143 use Symfony\Component\Security\Core\User\UserProviderInterface;
142144 use Symfony\Component\Security\Core\User\User;
145+ use Symfony\Component\Security\Core\User\UserInterface;
146+ use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
143147
144148 class ApiKeyUserProvider extends UserProviderInterface
145149 {
146150 public function getUsernameForApiKey($apiKey)
147151 {
148152 // Look up the username based on the token in the database, via
149153 // an API call, or do something entirely different
150- $username =// ...
154+ $username = ...;
151155
152156 return $username;
153157 }
@@ -174,7 +178,7 @@ The ``$userProvider`` might look something like this::
174178
175179 public function supportsClass($class)
176180 {
177- return$class === 'Symfony\Component\Security\Core\User\User';
181+ return 'Symfony\Component\Security\Core\User\User' === $class ;
178182 }
179183 }
180184
@@ -183,23 +187,23 @@ The ``$userProvider`` might look something like this::
183187 Read the dedicated article to learn
184188:doc: `how to create a custom user provider </cookbook/security/custom_provider >`.
185189
186- The logic inside ``getUsernameForApiKey `` is up to you. You may somehow transform
190+ The logic inside ``getUsernameForApiKey() `` is up to you. You may somehow transform
187191the API key (e.g. ``37b51d ``) into a username (e.g. ``jondoe ``) by looking
188192up some information in a "token" database table.
189193
190- The same is true for ``loadUserByUsername ``. In this example, Symfony's core
194+ The same is true for ``loadUserByUsername() ``. In this example, Symfony's core
191195:class: `Symfony\\ Component\\ Security\\ Core\\ User\\ User ` class is simply created.
192196This makes sense if you don't need to store any extra information on your
193197User object (e.g. ``firstName ``). But if you do, you may instead have your *own *
194198user class which you create and populate here by querying a database. This
195- would allow you to have custom data on the User object.
199+ would allow you to have custom data on the`` User `` object.
196200
197- Finally, just make sure that ``supportsClass ``return ``true `` for User
198- objects with the same class as whatever user you return in ``loadUserByUsername ``.
201+ Finally, just make sure that ``supportsClass() ``returns ``true `` for User
202+ objects with the same class as whatever user you return in ``loadUserByUsername() ``.
199203If your authentication is stateless like in this example (i.e. you expect
200204the user to send the API key with every request and so you don't save the
201205login to the session), then you can simply throw the ``UnsupportedUserException ``
202- exception in ``refreshUser ``.
206+ exception in ``refreshUser() ``.
203207
204208..note ::
205209
@@ -212,9 +216,10 @@ Configuration
212216-------------
213217
214218Once you have your ``ApiKeyAuthentication `` all setup, you need to register
215- it as a service and use it in ``security.yml ``. First, register it as a service.
216- This assumes that you have already setup your custom user provider as a service
217- called ``your_api_key_user_provider `` (see:doc: `/cookbook/security/custom_provider `).
219+ it as a service and use it in your security configuration (e.g. ``security.yml ``).
220+ First, register it as a service. This assumes that you have already setup
221+ your custom user provider as a service called ``your_api_key_user_provider ``
222+ (see:doc: `/cookbook/security/custom_provider `).
218223
219224..configuration-block ::
220225
@@ -260,8 +265,8 @@ called ``your_api_key_user_provider`` (see :doc:`/cookbook/security/custom_provi
260265 array(new Reference('your_api_key_user_provider'))
261266 ));
262267
263- Now, activate it in the ``firewalls `` section of`` security.yml `` using the
264- ``simple_preauth `` key:
268+ Now, activate it in the ``firewalls `` section ofyour security configuration
269+ using the ``simple_preauth `` key:
265270
266271..configuration-block ::
267272
@@ -395,32 +400,31 @@ configuration or set it to ``false``:
395400 Storing authentication information in the session works like this:
396401
397402#. At the end of each request, Symfony serializes the token object (returned
398- from ``authenticateToken ``), which also serializes the User object (since
399- it's set on a property on the token);
400- #. On the next request the token is deserialized and the deserialized User
401- object is passed to the ``refreshUser `` function of the user provider.
403+ from ``authenticateToken() ``), which also serializes the`` User `` object
404+ (since it's set on a property on the token);
405+ #. On the next request the token is deserialized and the deserialized`` User ``
406+ object is passed to the ``refreshUser() `` function of the user provider.
402407
403- The second step is the important one: Symfony calls ``refreshUser `` and passes
408+ The second step is the important one: Symfony calls ``refreshUser() `` and passes
404409you the user object that was serialized in the session. If your users are
405410stored in the database, then you may want to re-query for a fresh version
406411of the user to make sure it's not out-of-date. But regardless of your requirements,
407- ``refreshUser `` should now return the User object::
412+ ``refreshUser() `` should now return the User object::
408413
409414 // src/Acme/HelloBundle/Security/ApiKeyUserProvider.php
410415
411416 // ...
412-
413417 class ApiKeyUserProvider extends UserProviderInterface
414418 {
415419 // ...
416420
417421 public function refreshUser(UserInterface $user)
418422 {
419- // $user is the User that you set in the token inside authenticateToken
423+ // $user is the User that you set in the token inside authenticateToken()
420424 // after it has been deserialized from the session
421425
422426 // you might use $user to query the database for a fresh user
423- $id = $user->getId();
427+ // $id = $user->getId();
424428 // use $id to make a query
425429
426430 // if you are *not* reading from a database and are just creating
@@ -431,12 +435,12 @@ of the user to make sure it's not out-of-date. But regardless of your requiremen
431435
432436..note ::
433437
434- You'll also want to make sure that your User object is being serialized
435- correctly. If your User object has private properties, PHP can't serialize
438+ You'll also want to make sure that your`` User `` object is being serialized
439+ correctly. If your`` User `` object has private properties, PHP can't serialize
436440 those. In this case, you may get back a User object that has a ``null ``
437441 value for each property. For an example, see:doc: `/cookbook/security/entity_provider `.
438442
439- Only Authenticating forcertain URLs
443+ Only Authenticating forCertain URLs
440444------------------------------------
441445
442446This entry has assumed that you want to look for the ``apikey `` authentication
@@ -445,12 +449,13 @@ really need to look for authentication information once the user has reached
445449a certain URL (e.g. the redirect URL in OAuth).
446450
447451Fortunately, handling this situation is easy: just check to see what the
448- current URL is before creating the token in ``createToken ``::
452+ current URL is before creating the token in ``createToken() ``::
449453
450454 // src/Acme/HelloBundle/Security/ApiKeyAuthenticator.php
451455
452456 // ...
453457 use Symfony\Component\Security\Http\HttpUtils;
458+ use Symfony\Component\HttpFoundation\Request;
454459
455460 class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface
456461 {
@@ -477,8 +482,8 @@ current URL is before creating the token in ``createToken``::
477482 }
478483 }
479484
480- This usesa handy:class: `Symfony\\ Component\\ Security\\ Http\\ HttpUtils `
481- class tosee if the current URL matches the URL you're looking for. In this
485+ This usesthe handy:class: `Symfony\\ Component\\ Security\\ Http\\ HttpUtils `
486+ class tocheck if the current URL matches the URL you're looking for. In this
482487case, the URL (``/login/check ``) has been hardcoded in the class, but you
483488could also inject it as the third constructor argument.
484489