Passed
Pull Request — master (#1255)
by
unknown
56:50 queued 21:45
created

BearerTokenValidator   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 33
c 1
b 0
f 0
dl 0
loc 131
rs 10
wmc 13

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getTokenFromRequest() 0 6 1
A __construct() 0 3 1
A initJwtConfiguration() 0 11 2
A isTokenRevoked() 0 3 1
A validateIntrospectionRequest() 0 4 2
A validateIntrospection() 0 18 4
A isTokenValid() 0 5 1
A setPublicKey() 0 5 1
1
<?php
2
3
namespace League\OAuth2\Server\IntrospectionValidators;
4
5
use DateTimeZone;
6
use InvalidArgumentException;
7
use Lcobucci\Clock\SystemClock;
8
use Lcobucci\JWT\Configuration;
9
use Lcobucci\JWT\Signer\Key\InMemory;
10
use Lcobucci\JWT\Signer\Rsa\Sha256;
11
use Lcobucci\JWT\Token;
12
use Lcobucci\JWT\Validation\Constraint\SignedWith;
13
use Lcobucci\JWT\Validation\Constraint\StrictValidAt;
14
use Lcobucci\JWT\Validation\Constraint\ValidAt;
15
use League\OAuth2\Server\CryptKey;
16
use League\OAuth2\Server\Exception\OAuthServerException;
17
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
18
use Psr\Http\Message\ServerRequestInterface;
19
20
class BearerTokenValidator implements IntrospectionValidatorInterface
21
{
22
    /**
23
     * @var AccessTokenRepositoryInterface
24
     */
25
    private $accessTokenRepository;
26
27
    /**
28
     * @var CryptKey
29
     */
30
    protected $publicKey;
31
32
    /**
33
     * @var Configuration
34
     */
35
    protected $jwtConfiguration;
36
37
    /**
38
     * @param AccessTokenRepositoryInterface $accessTokenRepository
39
     */
40
    public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
41
    {
42
        $this->accessTokenRepository = $accessTokenRepository;
43
    }
44
45
    /**
46
     * Set the private key.
47
     *
48
     * @param CryptKey $key
49
     */
50
    public function setPublicKey(CryptKey $key): void
51
    {
52
        $this->publicKey = $key;
53
54
        $this->initJwtConfiguration();
55
    }
56
57
    /**
58
     * Initialise the JWT configuration.
59
     */
60
    private function initJwtConfiguration(): void
61
    {
62
        $this->jwtConfiguration = Configuration::forSymmetricSigner(new Sha256(), InMemory::empty());
63
64
        $this->jwtConfiguration->setValidationConstraints(
65
            \class_exists(StrictValidAt::class)
66
                ? new StrictValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get())))
67
                : new ValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))),
0 ignored issues
show
Deprecated Code introduced by
The class Lcobucci\JWT\Validation\Constraint\ValidAt has been deprecated: Use \Lcobucci\JWT\Validation\Constraint\LooseValidAt ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

67
                : /** @scrutinizer ignore-deprecated */ new ValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))),
Loading history...
68
            new SignedWith(
69
                new Sha256(),
70
                InMemory::plainText($this->publicKey->getKeyContents(), $this->publicKey->getPassPhrase() ?? '')
71
            )
72
        );
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function validateIntrospection(ServerRequestInterface $request): bool
79
    {
80
        $this->validateIntrospectionRequest($request);
81
82
        try {
83
            $token = $this->getTokenFromRequest($request);
84
        } catch (InvalidArgumentException $e) {
85
            return false;
86
        }
87
88
        if (
89
            !$this->isTokenValid($token) ||
90
            $this->isTokenRevoked($token)
91
        ) {
92
            return false;
93
        }
94
95
        return true;
96
    }
97
98
    /**
99
     * Gets the token from the request body.
100
     *
101
     * @param ServerRequestInterface $request
102
     *
103
     * @return Token
104
     */
105
    public function getTokenFromRequest(ServerRequestInterface $request): Token
106
    {
107
        $jwt = $request->getParsedBody()['token'] ?? '';
108
109
        return $this->jwtConfiguration->parser()
110
            ->parse($jwt);
111
    }
112
113
    /**
114
     * Validate the introspection request.
115
     *
116
     * @param ServerRequestInterface $request
117
     *
118
     * @throws OAuthServerException
119
     */
120
    private function validateIntrospectionRequest(ServerRequestInterface $request): void
121
    {
122
        if ($request->getMethod() !== 'POST') {
123
            throw OAuthServerException::accessDenied('Invalid request method');
124
        }
125
    }
126
127
    /**
128
     * Check if the given token is revoked.
129
     *
130
     * @param Token $token
131
     *
132
     * @return bool
133
     */
134
    private function isTokenRevoked(Token $token): bool
135
    {
136
        return $this->accessTokenRepository->isAccessTokenRevoked($token->claims()->get('jti'));
137
    }
138
139
    /**
140
     * Check if the given token is valid
141
     *
142
     * @param Token $token
143
     *
144
     * @return bool
145
     */
146
    private function isTokenValid(Token $token): bool
147
    {
148
        $constraints = $this->jwtConfiguration->validationConstraints();
149
150
        return $this->jwtConfiguration->validator()->validate($token, ...$constraints);
151
    }
152
}
153