Passed
Pull Request — master (#1255)
by
unknown
31:12
created

BearerTokenValidator::isTokenValid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
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\LooseValidAt;
13
use Lcobucci\JWT\Validation\Constraint\SignedWith;
14
use Lcobucci\JWT\Validation\Constraint\StrictValidAt;
15
use Lcobucci\JWT\Validation\Constraint\ValidAt;
16
use League\OAuth2\Server\CryptKey;
17
use League\OAuth2\Server\Exception\OAuthServerException;
18
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
19
use Psr\Http\Message\ServerRequestInterface;
20
21
class BearerTokenValidator implements IntrospectionValidatorInterface
22
{
23
    /**
24
     * @var AccessTokenRepositoryInterface
25
     */
26
    private $accessTokenRepository;
27
28
    /**
29
     * @var CryptKey
30
     */
31
    protected $publicKey;
32
33
    /**
34
     * @var Configuration
35
     */
36
    protected $jwtConfiguration;
37
38
    /**
39
     * @param AccessTokenRepositoryInterface $accessTokenRepository
40
     */
41
    public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
42
    {
43
        $this->accessTokenRepository = $accessTokenRepository;
44
    }
45
46
    /**
47
     * Set the private key.
48
     *
49
     * @param CryptKey $key
50
     */
51
    public function setPublicKey(CryptKey $key): void
52
    {
53
        $this->publicKey = $key;
54
55
        $this->initJwtConfiguration();
56
    }
57
58
    /**
59
     * Initialise the JWT configuration.
60
     */
61
    private function initJwtConfiguration(): void
62
    {
63
        $this->jwtConfiguration = Configuration::forSymmetricSigner(new Sha256(), InMemory::empty());
64
65
        $this->jwtConfiguration->setValidationConstraints(
66
            \class_exists(StrictValidAt::class)
67
                ? new StrictValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get())))
68
                : 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

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