@@ -41,7 +41,7 @@ value and then a User object is created::
41
41
// $apiKey = $request->headers->get('apikey');
42
42
43
43
if (!$apiKey) {
44
- throw new BadCredentialsException('No API key found' );
44
+ throw new BadCredentialsException();
45
45
46
46
// or to just skip api key authentication
47
47
// return null;
@@ -54,6 +54,11 @@ value and then a User object is created::
54
54
);
55
55
}
56
56
57
+ public function supportsToken(TokenInterface $token, $providerKey)
58
+ {
59
+ return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
60
+ }
61
+
57
62
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
58
63
{
59
64
if (!$userProvider instanceof ApiKeyUserProvider) {
@@ -83,16 +88,11 @@ value and then a User object is created::
83
88
$user->getRoles()
84
89
);
85
90
}
86
-
87
- public function supportsToken(TokenInterface $token, $providerKey)
88
- {
89
- return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
90
- }
91
91
}
92
92
93
93
Once you've :ref: `configured <cookbook-security-api-key-config >` everything,
94
94
you'll be able to authenticate by adding an apikey parameter to the query
95
- string, like ``http://example.com/admin /foo?apikey=37b51d194a7513e45b56f6524f2d51f2 ``.
95
+ string, like ``http://example.com/api /foo?apikey=37b51d194a7513e45b56f6524f2d51f2 ``.
96
96
97
97
The authentication process has several steps, and your implementation will
98
98
probably differ:
@@ -177,7 +177,7 @@ The ``$userProvider`` might look something like this::
177
177
null,
178
178
// the roles for the user - you may choose to determine
179
179
// these dynamically somehow based on the user
180
- array('ROLE_USER ')
180
+ array('ROLE_API ')
181
181
);
182
182
}
183
183
@@ -249,6 +249,7 @@ would allow you to have custom data on the ``User`` object.
249
249
250
250
Finally, just make sure that ``supportsClass() `` returns ``true `` for User
251
251
objects with the same class as whatever user you return in ``loadUserByUsername() ``.
252
+
252
253
If your authentication is stateless like in this example (i.e. you expect
253
254
the user to send the API key with every request and so you don't save the
254
255
login to the session), then you can simply throw the ``UnsupportedUserException ``
@@ -262,7 +263,7 @@ exception in ``refreshUser()``.
262
263
Handling Authentication Failure
263
264
-------------------------------
264
265
265
- In order for your ``ApiKeyAuthenticator `` to correctly display a 403
266
+ In order for your ``ApiKeyAuthenticator `` to correctly display a 401
266
267
http status when either bad credentials or authentication fails you will
267
268
need to implement the :class: `Symfony\\ Component\\ Security\\ Http\\ Authentication\\ AuthenticationFailureHandlerInterface ` on your
268
269
Authenticator. This will provide a method ``onAuthenticationFailure `` which
@@ -285,7 +286,7 @@ you can use to create an error ``Response``.
285
286
286
287
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
287
288
{
288
- return new Response("Authentication Failed.", 403 );
289
+ return new Response("Authentication Failed.", 401 );
289
290
}
290
291
}
291
292
@@ -353,7 +354,7 @@ using the ``simple_preauth`` and ``provider`` keys respectively:
353
354
354
355
firewalls :
355
356
secured_area :
356
- pattern : ^/admin
357
+ pattern : ^/api
357
358
stateless : true
358
359
simple_preauth :
359
360
authenticator : apikey_authenticator
@@ -376,7 +377,7 @@ using the ``simple_preauth`` and ``provider`` keys respectively:
376
377
<!-- ... -->
377
378
378
379
<firewall name =" secured_area"
379
- pattern =" ^/admin "
380
+ pattern =" ^/api "
380
381
stateless =" true"
381
382
provider =" api_key_user_provider"
382
383
>
@@ -396,7 +397,7 @@ using the ``simple_preauth`` and ``provider`` keys respectively:
396
397
$container->loadFromExtension('security', array(
397
398
'firewalls' => array(
398
399
'secured_area' => array(
399
- 'pattern' => '^/admin ',
400
+ 'pattern' => '^/api ',
400
401
'stateless' => true,
401
402
'simple_preauth' => array(
402
403
'authenticator' => 'apikey_authenticator',
@@ -411,6 +412,44 @@ using the ``simple_preauth`` and ``provider`` keys respectively:
411
412
),
412
413
));
413
414
415
+ If you have defined ``access_control ``, make sure to add a new entry:
416
+
417
+ .. configuration-block ::
418
+
419
+ .. code-block :: yaml
420
+
421
+ # app/config/security.yml
422
+ security :
423
+ # ...
424
+
425
+ access_control :
426
+ - { path: ^/api, roles: ROLE_API }
427
+
428
+ .. code-block :: xml
429
+
430
+ <!-- app/config/security.xml -->
431
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
432
+ <srv : container xmlns =" http://symfony.com/schema/dic/security"
433
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
434
+ xmlns : srv =" http://symfony.com/schema/dic/services"
435
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
436
+ http://symfony.com/schema/dic/services/services-1.0.xsd" >
437
+
438
+ <rule path =" ^/api" role =" ROLE_API" />
439
+ </srv : container >
440
+
441
+ .. code-block :: php
442
+
443
+ // app/config/security.php
444
+ $container->loadFromExtension('security', array(
445
+ 'access_control' => array(
446
+ array(
447
+ 'path' => '^/api',
448
+ 'role' => 'ROLE_API',
449
+ ),
450
+ ),
451
+ ));
452
+
414
453
That's it! Now, your ``ApiKeyAuthenticator `` should be called at the beginning
415
454
of each request and your authentication process will take place.
416
455
@@ -443,7 +482,7 @@ configuration or set it to ``false``:
443
482
444
483
firewalls :
445
484
secured_area :
446
- pattern : ^/admin
485
+ pattern : ^/api
447
486
stateless : false
448
487
simple_preauth :
449
488
authenticator : apikey_authenticator
@@ -466,7 +505,7 @@ configuration or set it to ``false``:
466
505
<!-- ... -->
467
506
468
507
<firewall name =" secured_area"
469
- pattern =" ^/admin "
508
+ pattern =" ^/api "
470
509
stateless =" false"
471
510
provider =" api_key_user_provider"
472
511
>
@@ -485,7 +524,7 @@ configuration or set it to ``false``:
485
524
$container->loadFromExtension('security', array(
486
525
'firewalls' => array(
487
526
'secured_area' => array(
488
- 'pattern' => '^/admin ',
527
+ 'pattern' => '^/api ',
489
528
'stateless' => false,
490
529
'simple_preauth' => array(
491
530
'authenticator' => 'apikey_authenticator',
0 commit comments