1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Firesphere\GraphQLJWT; |
4
|
|
|
|
5
|
|
|
use Lcobucci\JWT\Builder; |
6
|
|
|
use Lcobucci\JWT\Parser; |
7
|
|
|
use Lcobucci\JWT\Signer\Hmac\Sha256; |
8
|
|
|
use SilverStripe\Control\Director; |
9
|
|
|
use SilverStripe\Control\HTTPRequest; |
10
|
|
|
use SilverStripe\Core\Config\Configurable; |
11
|
|
|
use SilverStripe\Dev\Debug; |
12
|
|
|
use SilverStripe\GraphQL\Controller; |
13
|
|
|
use SilverStripe\ORM\ValidationResult; |
14
|
|
|
use SilverStripe\Security\Authenticator; |
15
|
|
|
use SilverStripe\Security\Member; |
16
|
|
|
use SilverStripe\Security\MemberAuthenticator\MemberAuthenticator; |
17
|
|
|
|
18
|
|
|
class JWTAuthenticator extends MemberAuthenticator |
19
|
|
|
{ |
20
|
|
|
use Configurable; |
21
|
|
|
|
22
|
|
|
public function supportedServices() |
23
|
|
|
{ |
24
|
|
|
return Authenticator::LOGIN | Authenticator::CMS_LOGIN; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @param array $data |
29
|
|
|
* @param HTTPRequest $request |
30
|
|
|
* @param ValidationResult|null $result |
31
|
|
|
* @return Member|null |
32
|
|
|
* @throws \BadMethodCallException |
33
|
|
|
* @throws \OutOfBoundsException |
34
|
|
|
*/ |
35
|
|
|
public function authenticate(array $data, HTTPRequest $request, ValidationResult &$result = null) |
36
|
|
|
{ |
37
|
|
|
if (!$result) { |
38
|
|
|
$result = new ValidationResult(); |
39
|
|
|
} |
40
|
|
|
$token = $data['token']; |
41
|
|
|
$parser = new Parser(); |
42
|
|
|
$parsedToken = $parser->parse((string)$token); |
43
|
|
|
$signer = new Sha256(); |
44
|
|
|
$signerKey = static::config()->get('signer_key'); |
45
|
|
|
$member = null; |
46
|
|
|
|
47
|
|
|
if (!$parsedToken->verify($signer, $signerKey)) { |
|
|
|
|
48
|
|
|
$result->addError('Invalid token'); |
49
|
|
|
} |
50
|
|
|
if ($parsedToken->isExpired()) { |
51
|
|
|
$result->addError('Token is expired'); |
52
|
|
|
} |
53
|
|
|
if ($parsedToken->getClaim('uid')) { |
|
|
|
|
54
|
|
|
/** @var Member $member */ |
55
|
|
|
$member = Member::get()->byID($parsedToken->getClaim('uid')); |
|
|
|
|
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
return $result->isValid() ? $member : null; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param Member $member |
63
|
|
|
* @return \Lcobucci\JWT\Token |
64
|
|
|
* @throws \BadMethodCallException |
65
|
|
|
*/ |
66
|
|
|
public function generateToken(Member $member) |
67
|
|
|
{ |
68
|
|
|
$config = static::config(); |
69
|
|
|
$signer = new Sha256(); |
70
|
|
|
$uniqueID = uniqid($config->get('prefix'), true); |
71
|
|
|
|
72
|
|
|
$request = Controller::curr()->getRequest(); |
73
|
|
|
$audience = $request->getHeader('Origin'); |
74
|
|
|
$signerKey = $config->get('signer_key'); |
75
|
|
|
|
76
|
|
|
$builder = new Builder(); |
77
|
|
|
$token = $builder |
|
|
|
|
78
|
|
|
// Configures the issuer (iss claim) |
79
|
|
|
->setIssuer(Director::absoluteBaseURL()) |
|
|
|
|
80
|
|
|
// Configures the audience (aud claim) |
81
|
|
|
->setAudience($audience) |
82
|
|
|
// Configures the id (jti claim), replicating as a header item |
83
|
|
|
->setId($uniqueID, true) |
84
|
|
|
// Configures the time that the token was issue (iat claim) |
85
|
|
|
->setIssuedAt(time()) |
86
|
|
|
// Configures the time that the token can be used (nbf claim) |
87
|
|
|
->setNotBefore(time() + $config->get('nbf_time')) |
88
|
|
|
// Configures the expiration time of the token (nbf claim) |
89
|
|
|
->setExpiration(time() + $config->get('nbf_expiration')) |
90
|
|
|
// Configures a new claim, called "uid" |
91
|
|
|
->set('uid', $member->ID) |
92
|
|
|
// Sign the key with the Signer's key @todo: support certificates |
93
|
|
|
->sign($signer, $signerKey); |
94
|
|
|
|
95
|
|
|
// Return the token |
96
|
|
|
return $token->getToken(); |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.