Skip to content

Commit 25a4531

Browse files
committed
First words about the access tokens
1 parent dc15ca3 commit 25a4531

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

security.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,15 @@ website.
11741174

11751175
You can learn all about this authenticator in :doc:`/security/login_link`.
11761176

1177+
Access Tokens
1178+
~~~~~~~~~~~~~~
1179+
1180+
Access Tokens are often used in API contexts.
1181+
The user will receive a short-lived token from an authorization server
1182+
which will authenticate them.
1183+
1184+
You can learn all about this authenticator in :doc:`/security/access_token`.
1185+
11771186
X.509 Client Certificates
11781187
~~~~~~~~~~~~~~~~~~~~~~~~~
11791188

security/access_token.rst

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
.. index::
2+
single: Security; Access Token
3+
4+
How to use Access Token Authentication
5+
======================================
6+
7+
Access tokens are commonly used in API contexts. The access token is is obtained
8+
through an authorization server (or similar) whose role is to verify the user identity
9+
and receive consent before the token is issued.
10+
11+
Access Tokens can be of any kind: opaque strings, Json Web Tokens (JWT) or SAML2 (XML structures).
12+
13+
Using the Access Token Authenticator
14+
----------------------------------
15+
16+
This guide assumes you have setup security and have created a user object
17+
in your application. Follow :doc:`the main security guide </security>` if
18+
this is not yet the case.
19+
20+
1) Configure the Access Token Authenticator
21+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22+
23+
The access token authenticator can be configured using three different options:
24+
25+
* ``header_token``: the token is sent through the request header. Usually ``Authorization`` with the ``Bearer`` scheme.
26+
* ``query_token``: the token is part of the query string. Usually ``access_token``.
27+
* ``body_token``: the token is part of the request body during a POST request. Usually ``access_token``.
28+
29+
You must configure a ``token_handler`` when enabling this authenticator.
30+
The token handler is a service that is able to load and verify the token (e.g. expiration, digital signature...)
31+
and return the associated user identifier.
32+
33+
.. configuration-block::
34+
35+
.. code-block:: yaml
36+
37+
# config/packages/security.yaml
38+
security:
39+
firewalls:
40+
main:
41+
header_token:
42+
token_handler: App\Security\AccessTokenHandler
43+
44+
2) Create your Access Token Handler
45+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46+
47+
Now that the authenticator is able to check the access tokens, you must
48+
create your access token handler.
49+
50+
This handler shall implement the interface
51+
:class:`Symfony\\Component\\Security\\Http\\Authenticator\\AccessTokenHandlerInterface`.
52+
In the following example, the handler will retrieve the token from a database
53+
using a fictive Doctrine repository.
54+
55+
.. configuration-block::
56+
57+
.. code-block:: php
58+
59+
// src/Security/AccessTokenHandler.php
60+
namespace App\Controller;
61+
62+
use App\Repository\AccessTokenRepository;
63+
use Symfony\Component\Security\Http\Authenticator\AccessTokenHandlerInterface;
64+
65+
class AccessTokenHandler implements AccessTokenHandlerInterface
66+
{
67+
public function __construct(private readonly AccessTokenRepository $repository)
68+
{
69+
}
70+
71+
public function getUserIdentifierFrom(string $token): string
72+
{
73+
$accessToken = $this->repository->findOneByValue($token);
74+
if ($accessToken === null || !$accessToken->isValid()) {
75+
throw new BadCredentialsException('Invalid credentials.');
76+
}
77+
78+
return $accessToken->getUserId();
79+
}
80+
}
81+
82+
.. caution::
83+
84+
It is important to check the token is valid.
85+
For instance, in the example we verify the token has not expired.
86+
With self-contained access tokens such as JWT, the handler is required to
87+
verify the digital signature and understand all claims,
88+
especially `iat`, `nbf` and `exp`.
89+
90+
Important Security Considerations
91+
---------------------------------
92+
93+
Because of the security weaknesses associated with the URI method,
94+
including the high likelihood that the URL containing the access token will be logged,
95+
it **SHOULD NOT** be used unless it is impossible to transport the access token in the
96+
request header field or the HTTP request entity-body.
97+
98+
The request body method **SHOULD NOT** be used except in application contexts
99+
where participating browsers do not have access to the "Authorization" request header field.
100+
101+
In other words: ``query_token`` and ``body_token` authenticators are not recommended.
102+
103+
Customizing the Success Handler
104+
-------------------------------
105+
106+
Sometimes, the default success handling does not fit your use-case (e.g.
107+
when you need to generate and return additional response header parameters).
108+
To customize how the success handler behaves, create your own handler as a class that implements
109+
:class:`Symfony\\Component\\Security\\Http\\Authentication\\AuthenticationSuccessHandlerInterface`::
110+
111+
// src/Security/Authentication/AuthenticationSuccessHandler.php
112+
namespace App\Security\Authentication;
113+
114+
use Symfony\Component\HttpFoundation\JsonResponse;
115+
use Symfony\Component\HttpFoundation\Request;
116+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
117+
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
118+
119+
class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
120+
{
121+
public function onAuthenticationSuccess(Request $request, TokenInterface $token): JsonResponse
122+
{
123+
$user = $token->getUser();
124+
$userApiToken = $user->getApiToken();
125+
126+
return new JsonResponse(['apiToken' => $userApiToken]);
127+
}
128+
}
129+
130+
Then, configure this service ID as the ``success_handler``:
131+
132+
.. configuration-block::
133+
134+
.. code-block:: yaml
135+
136+
# config/packages/security.yaml
137+
security:
138+
firewalls:
139+
main:
140+
header_token:
141+
token_handler: App\Security\AccessTokenHandler
142+
success_handler: App\Security\Authentication\AuthenticationSuccessHandler
143+
144+
.. tip::
145+
146+
If you want to customize the default failure handling, use the
147+
``failure_handler`` option and create a class that implements
148+
:class:`Symfony\\Component\\Security\\Http\\Authentication\\AuthenticationFailureHandlerInterface`.

0 commit comments

Comments
 (0)