Completed
Pull Request — master (#910)
by Andrew
01:49
created

BearerTokenValidator::validateAuthorization()   B

Complexity

Conditions 8
Paths 26

Size

Total Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 47
ccs 24
cts 24
cp 1
rs 7.9119
cc 8
nc 26
nop 1
crap 8
1
<?php
2
/**
3
 * @author      Alex Bilbie <[email protected]>
4
 * @copyright   Copyright (c) Alex Bilbie
5
 * @license     http://mit-license.org/
6
 *
7
 * @link        https://github.com/thephpleague/oauth2-server
8
 */
9
10
namespace League\OAuth2\Server\AuthorizationValidators;
11
12
use Lcobucci\JWT\Parser;
13
use Lcobucci\JWT\Signer\Rsa\Sha256;
14
use Lcobucci\JWT\ValidationData;
15
use League\OAuth2\Server\CryptKey;
16
use League\OAuth2\Server\CryptTrait;
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 AuthorizationValidatorInterface
22
{
23
    use CryptTrait;
24
25
    /**
26
     * @var AccessTokenRepositoryInterface
27
     */
28
    private $accessTokenRepository;
29
30
    /**
31
     * @var \League\OAuth2\Server\CryptKey
32
     */
33
    protected $publicKey;
34
35
    /**
36
     * @param AccessTokenRepositoryInterface $accessTokenRepository
37
     */
38 10
    public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
39
    {
40 10
        $this->accessTokenRepository = $accessTokenRepository;
41 10
    }
42
43
    /**
44
     * Set the public key
45
     *
46
     * @param \League\OAuth2\Server\CryptKey $key
47
     */
48 10
    public function setPublicKey(CryptKey $key)
49
    {
50 10
        $this->publicKey = $key;
51 10
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 10
    public function validateAuthorization(ServerRequestInterface $request)
57
    {
58 10
        if ($request->hasHeader('authorization') === false) {
59 1
            throw OAuthServerException::accessDenied('Missing "Authorization" header');
60
        }
61
62 9
        $header = $request->getHeader('authorization');
63 9
        $jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header[0]));
64
65
        try {
66
            // Attempt to parse and validate the JWT
67 9
            $token = (new Parser())->parse($jwt);
68
            try {
69 6
                if ($token->verify(new Sha256(), $this->publicKey->getKeyPath()) === false) {
70 5
                    throw OAuthServerException::accessDenied('Access token could not be verified');
71
                }
72 2
            } catch (\BadMethodCallException $exception) {
73 1
                throw OAuthServerException::accessDenied('Access token is not signed');
74
            }
75
76
            // Ensure access token hasn't expired
77 4
            $data = new ValidationData();
78 4
            $data->setCurrentTime(time());
79
80 4
            if ($token->validate($data) === false) {
81 1
                throw OAuthServerException::accessDenied('Access token is invalid');
82
            }
83
84
            // Check if token has been revoked
85 3
            if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
86 1
                throw OAuthServerException::accessDenied('Access token has been revoked');
87
            }
88
89
            // Return the request with additional attributes
90
            return $request
91 2
                ->withAttribute('oauth_access_token_id', $token->getClaim('jti'))
92 2
                ->withAttribute('oauth_client_id', $token->getClaim('aud'))
93 2
                ->withAttribute('oauth_user_id', $token->getClaim('sub'))
94 2
                ->withAttribute('oauth_scopes', $token->getClaim('scopes'));
95 7
        } catch (\InvalidArgumentException $exception) {
96
            // JWT couldn't be parsed so return the request as is
97 2
            throw OAuthServerException::accessDenied($exception->getMessage());
98 5
        } catch (\RuntimeException $exception) {
99
            //JWR couldn't be parsed so return the request as is
100 1
            throw OAuthServerException::accessDenied('Error while decoding to JSON');
101
        }
102
    }
103
}
104