Completed
Pull Request — master (#851)
by Maxime
31:14
created

BearerTokenValidator::appendAttributesFromToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 6
nc 1
nop 2
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\Token;
15
use Lcobucci\JWT\ValidationData;
16
use League\OAuth2\Server\CryptKey;
17
use League\OAuth2\Server\CryptTrait;
18
use League\OAuth2\Server\Exception\OAuthServerException;
19
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
20
use Psr\Http\Message\ServerRequestInterface;
21
22
class BearerTokenValidator implements AuthorizationValidatorInterface
23
{
24
    use CryptTrait;
25
26
    /**
27
     * @var AccessTokenRepositoryInterface
28
     */
29
    private $accessTokenRepository;
30
31
    /**
32
     * @var \League\OAuth2\Server\CryptKey
33
     */
34
    protected $publicKey;
35
36
    /**
37
     * @param AccessTokenRepositoryInterface $accessTokenRepository
38
     */
39
    public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
40
    {
41
        $this->accessTokenRepository = $accessTokenRepository;
42
    }
43
44
    /**
45
     * Set the public key
46
     *
47
     * @param \League\OAuth2\Server\CryptKey $key
48
     */
49
    public function setPublicKey(CryptKey $key)
50
    {
51
        $this->publicKey = $key;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function validateAuthorization(ServerRequestInterface $request)
58
    {
59
        if ($request->hasHeader('authorization') === false) {
60
            throw OAuthServerException::accessDenied('Missing "Authorization" header');
61
        }
62
63
        $header = $request->getHeader('authorization');
64
        $jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header[0]));
65
66
        try {
67
            // Attempt to parse and validate the JWT
68
            $token = (new Parser())->parse($jwt);
69
            if ($token->verify(new Sha256(), $this->publicKey->getKeyPath()) === false) {
70
                throw OAuthServerException::accessDenied('Access token could not be verified');
71
            }
72
73
            // Ensure access token hasn't expired
74
            $data = new ValidationData();
75
            $data->setCurrentTime(time());
76
77
            if ($token->validate($data) === false) {
78
                throw OAuthServerException::accessDenied('Access token is invalid');
79
            }
80
81
            // Check if token has been revoked
82
            if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
83
                throw OAuthServerException::accessDenied('Access token has been revoked');
84
            }
85
86
            // Return the request with additional attributes
87
            return $this->appendAttributesFromToken($request, $token);
88
        } catch (\InvalidArgumentException $exception) {
89
            // JWT couldn't be parsed so return the request as is
90
            throw OAuthServerException::accessDenied($exception->getMessage());
91
        } catch (\RuntimeException $exception) {
92
            //JWR couldn't be parsed so return the request as is
93
            throw OAuthServerException::accessDenied('Error while decoding to JSON');
94
        }
95
    }
96
97
    /**
98
     * @param ServerRequestInterface $request
99
     * @param Token $token
100
     * @return ServerRequestInterface
101
     */
102
    protected function appendAttributesFromToken(ServerRequestInterface $request, Token $token)
103
    {
104
        return $request
105
            ->withAttribute('oauth_access_token_id', $token->getClaim('jti'))
106
            ->withAttribute('oauth_client_id', $token->getClaim('aud'))
107
            ->withAttribute('oauth_user_id', $token->getClaim('sub'))
108
            ->withAttribute('oauth_scopes', $token->getClaim('scopes'));
109
    }
110
}
111