1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the KleijnWeb\JwtBundle package. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
*/ |
8
|
|
|
namespace KleijnWeb\JwtBundle\Authenticator; |
9
|
|
|
|
10
|
|
|
use Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface; |
11
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
12
|
|
|
use Symfony\Component\Security\Core\Exception\AuthenticationException; |
13
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; |
14
|
|
|
use Symfony\Component\HttpFoundation\Request; |
15
|
|
|
use Symfony\Component\Security\Core\User\UserProviderInterface; |
16
|
|
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* @author John Kleijn <[email protected]> |
20
|
|
|
*/ |
21
|
|
|
class Authenticator implements SimplePreAuthenticatorInterface |
|
|
|
|
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var JwtKey[] |
25
|
|
|
*/ |
26
|
|
|
private $keys = []; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @param JwtKey[] $keys |
30
|
|
|
*/ |
31
|
|
|
public function __construct(array $keys) |
32
|
|
|
{ |
33
|
|
|
foreach ($keys as $key) { |
34
|
|
|
$this->keys[$key->getId()] = $key; |
35
|
|
|
} |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @param string $id |
40
|
|
|
* |
41
|
|
|
* @return JwtKey |
42
|
|
|
*/ |
43
|
|
|
public function getKeyById($id) |
44
|
|
|
{ |
45
|
|
|
if ($id) { |
46
|
|
|
if (!isset($this->keys[$id])) { |
47
|
|
|
throw new AuthenticationException("Unknown 'kid' $id"); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
return $this->keys[$id]; |
51
|
|
|
} |
52
|
|
|
if (count($this->keys) > 1) { |
53
|
|
|
throw new AuthenticationException("Missing 'kid'"); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
return current($this->keys); |
|
|
|
|
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param Request $request |
61
|
|
|
* @param string $providerKey |
62
|
|
|
* |
63
|
|
|
* @return PreAuthenticatedToken |
64
|
|
|
*/ |
65
|
|
|
public function createToken(Request $request, $providerKey) |
66
|
|
|
{ |
67
|
|
|
$tokenString = $request->headers->get('Authorization'); |
68
|
|
|
|
69
|
|
|
if (0 === strpos($tokenString, 'Bearer ')) { |
70
|
|
|
$tokenString = substr($tokenString, 7); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
if (!$tokenString) { |
74
|
|
|
throw new BadCredentialsException('No API key found'); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
try { |
78
|
|
|
$token = new JwtToken($tokenString); |
79
|
|
|
$key = $this->getKeyById($token->getKeyId()); |
80
|
|
|
$key->validateToken($token); |
81
|
|
|
} catch (\Exception $e) { |
82
|
|
|
throw new AuthenticationException('Invalid key', 0, $e); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
return new PreAuthenticatedToken('anon.', $token, $providerKey); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @param TokenInterface $token |
90
|
|
|
* @param UserProviderInterface $userProvider |
91
|
|
|
* @param string $providerKey |
92
|
|
|
* |
93
|
|
|
* @return PreAuthenticatedToken |
94
|
|
|
*/ |
95
|
|
|
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) |
96
|
|
|
{ |
97
|
|
|
/** @var $jwtToken JwtToken */ |
98
|
|
|
if (!($jwtToken = $token->getCredentials()) instanceof JwtToken) { |
99
|
|
|
throw new \UnexpectedValueException("Expected credentials to be a JwtToken object"); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$user = $userProvider->loadUserByUsername($jwtToken->getSubject()); |
|
|
|
|
103
|
|
|
|
104
|
|
|
return new PreAuthenticatedToken($user, $token, $providerKey, $user->getRoles()); |
|
|
|
|
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* @param TokenInterface $token |
109
|
|
|
* @param string $providerKey |
110
|
|
|
* |
111
|
|
|
* @return bool |
112
|
|
|
*/ |
113
|
|
|
public function supportsToken(TokenInterface $token, $providerKey) |
114
|
|
|
{ |
115
|
|
|
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey; |
116
|
|
|
} |
117
|
|
|
} |
118
|
|
|
|
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.