· 6 years ago · Mar 31, 2020, 11:31 AM
1<?php
2namespace AppBundle\Security;
3
4use Symfony\Component\HttpFoundation\Request;
5use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
6use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
7use Symfony\Component\Security\Core\Exception\AuthenticationException;
8use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
9use Symfony\Component\Security\Core\Exception\BadCredentialsException;
10use Symfony\Component\Security\Core\User\UserProviderInterface;
11use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
12
13class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface {
14
15 public function createToken(Request $request, $providerKey)
16 {
17 // look for an token query parameter
18 $apiKey = $request->query->get('token');
19 if (empty($apiKey)) {
20 $session = $request->getSession();
21 $apiKey = $session->get('token');
22 }
23
24 // or if you want to use an "apikey" header, then do something like this:
25 // TODO use headers
26 // $apiKey = $request->headers->get('apikey');
27
28 if (!$apiKey) {
29 throw new BadCredentialsException('No API key found');
30 // or to just skip api key authentication
31 // return null;
32 }
33
34 return new PreAuthenticatedToken(
35 'anon.',
36 $apiKey,
37 $providerKey
38 );
39 }
40
41 public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
42 {
43 if (!$userProvider instanceof ApiKeyUserProvider) {
44 throw new \InvalidArgumentException(
45 sprintf(
46 'The user provider must be an instance of ApiKeyUserProvider (%s was given).',
47 get_class($userProvider)
48 )
49 );
50 }
51
52 $apiKey = $token->getCredentials();
53 $username = $userProvider->getUsernameForApiKey($apiKey);
54
55 if (!$username) {
56 // CAUTION: this message will be returned to the client
57 // (so don't put any un-trusted messages / error strings here)
58 throw new CustomUserMessageAuthenticationException(
59 sprintf('API Key "%s" does not exist.', $apiKey)
60 );
61 }
62
63 $user = $userProvider->loadUserByUsername($username);
64
65 return new PreAuthenticatedToken(
66 $user,
67 $apiKey,
68 $providerKey,
69 $user->getRoles()
70 );
71 }
72
73 public function supportsToken(TokenInterface $token, $providerKey)
74 {
75 return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
76 }
77}