Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security] Deprecate current system in favor of a JWTTokenAuthenticator (Guard) #184

Merged
merged 6 commits into from
Sep 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ For a diff between two versions https://github.com/lexik/LexikJWTAuthenticationB

## [2.0](https://github.com/lexik/LexikJWTAuthenticationBundle/tree/2.0)

* feature [\#230](https://github.com/lexik/LexikJWTAuthenticationBundle/pull/230) Introduce JWTExpiredEvent ([chalasr](https://github.com/chalasr))

* feature [\#184](https://github.com/lexik/LexikJWTAuthenticationBundle/pull/184) [Security] Deprecate current system in favor of a JWTTokenAuthenticator (Guard) ([chalasr](https://github.com/chalasr))

* feature [\#218](https://github.com/lexik/LexikJWTAuthenticationBundle/pull/218) Add more flexibility in token extractors configuration ([chalasr](https://github.com/chalasr))

* feature [\#217](https://github.com/lexik/LexikJWTAuthenticationBundle/pull/217) Refactor TokenExtractors loading for easy overriding ([chalasr](https://github.com/chalasr))
Expand All @@ -25,7 +29,7 @@ For a diff between two versions https://github.com/lexik/LexikJWTAuthenticationB

## [1.7.0](https://github.com/lexik/LexikJWTAuthenticationBundle/tree/v1.7.0) (2016-08-06)

* feature [\#200](https://github.com/lexik/LexikJWTAuthenticationBundle/pull/200) Depreciate injection of Request instances ([chalasr](https://github.com/chalasr))
* feature [\#200](https://github.com/lexik/LexikJWTAuthenticationBundle/pull/200) Deprecate injection of Request instances ([chalasr](https://github.com/chalasr))

## [v1.6.0](https://github.com/lexik/LexikJWTAuthenticationBundle/tree/v1.6.0) (2016-07-07)

Expand Down
14 changes: 8 additions & 6 deletions Encoder/DefaultEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ public function encode(array $payload)
try {
$jws = $this->jwsProvider->create($payload);
} catch (InvalidArgumentException $e) {
throw new JWTEncodeFailureException('An error occurred while trying to encode the JWT token.', $e);
throw new JWTEncodeFailureException(JWTEncodeFailureException::INVALID_CONFIG, 'An error occured while trying to encode the JWT token. Please verify your configuration (private key/passphrase)', $e);
}

if (!$jws->isSigned()) {
throw new JWTEncodeFailureException('Unable to create a signed JWT from the given configuration.');
throw new JWTEncodeFailureException(JWTEncodeFailureException::UNSIGNED_TOKEN, 'Unable to create a signed JWT from the given configuration.');
}

return $jws->getToken();
Expand All @@ -53,17 +53,19 @@ public function decode($token)
try {
$jws = $this->jwsProvider->load($token);
} catch (InvalidArgumentException $e) {
throw new JWTDecodeFailureException('Invalid JWT Token', $e);
throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid JWT Token', $e);
}

$payload = $jws->getPayload();

if ($jws->isExpired()) {
throw new JWTDecodeFailureException('Expired JWT token');
throw new JWTDecodeFailureException(JWTDecodeFailureException::EXPIRED_TOKEN, 'Expired JWT Token');
}

if (!$jws->isVerified()) {
throw new JWTDecodeFailureException('Unable to verify the given JWT through the given configuration. If the "lexik_jwt_authentication.encoder" encryption options have been changed since your last authentication, please renew the token. If the problem persists, verify that the configured keys/passphrase are valid.');
throw new JWTDecodeFailureException(JWTDecodeFailureException::UNVERIFIED_TOKEN, 'Unable to verify the given JWT through the given configuration. If the "lexik_jwt_authentication.encoder" encryption options have been changed since your last authentication, please renew the token. If the problem persists, verify that the configured keys/passphrase are valid.');
}

return $jws->getPayload();
return $payload;
}
}
8 changes: 5 additions & 3 deletions Encoder/JWTEncoderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ interface JWTEncoderInterface
*
* @return string the encoded token string
*
* @throws JWTEncodeFailureException If an error occurred during the creation of the token (invalid configuration...)
* @throws JWTEncodeFailureException If an error occurred while trying to create
* the token (invalid crypto key, invalid payload...)
*/
public function encode(array $data);

/**
* @param string $token
*
* @return false|array
* @return array
*
* @throws JWTDecodeFailureException If an error occurred during the loading of the token (invalid signature, expired token...)
* @throws JWTDecodeFailureException If an error occurred while trying to load the token
* (invalid signature, invalid crypto key, expired token...)
*/
public function decode($token);
}
12 changes: 12 additions & 0 deletions Event/JWTExpiredEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\Event;

/**
* JWTExpiredEvent.
*
* @author Robin Chalas <[email protected]>
*/
class JWTExpiredEvent extends AuthenticationFailureEvent implements JWTFailureEventInterface
{
}
7 changes: 7 additions & 0 deletions Events.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,11 @@ final class Events
* Hook into this event to set a custom response.
*/
const JWT_NOT_FOUND = 'lexik_jwt_authentication.on_jwt_not_found';

/**
* Dispatched when the token is expired.
* The expired token's payload can be retrieved by hooking into this event, so you can set a different
* response.
*/
const JWT_EXPIRED = 'lexik_jwt_authentication.on_jwt_expired';
}
23 changes: 23 additions & 0 deletions Exception/ExpiredTokenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

use Lexik\Bundle\JWTAuthenticationBundle\Security\Guard\JWTTokenAuthenticator;
use Symfony\Component\Security\Core\Exception\AuthenticationException;

/**
* Exception that should be thrown from a {@link JWTTokenAuthenticator} implementation during
* an authentication process.
*
* @author Robin Chalas <[email protected]>
*/
class ExpiredTokenException extends AuthenticationException
{
/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return 'Expired JWT Token';
}
}
34 changes: 34 additions & 0 deletions Exception/InvalidPayloadException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

use Symfony\Component\Security\Core\Exception\AuthenticationException;

/**
* Missing key in the token payload during authentication.
*
* @author Robin Chalas <[email protected]>
*/
class InvalidPayloadException extends AuthenticationException
{
/**
* @var string
*/
private $invalidKey;

/**
* @param string $invalidKey The key that cannot be found in the payload
*/
public function __construct($invalidKey)
{
$this->invalidKey = $invalidKey;
}

/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return sprintf('Unable to find key "%s" in the token payload.', $this->invalidKey);
}
}
21 changes: 21 additions & 0 deletions Exception/InvalidTokenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

use Symfony\Component\Security\Core\Exception\AuthenticationException;

/**
* Exception to be thrown in case of invalid token during an authentication process.
*
* @author Robin Chalas <[email protected]>
*/
class InvalidTokenException extends AuthenticationException
{
/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return 'Invalid JWT Token';
}
}
5 changes: 4 additions & 1 deletion Exception/JWTDecodeFailureException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

/**
* Base class for exceptions thrown during JWTEncoderInterface::decode().
* JWTDecodeFailureException is thrown if an error occurs in the token decoding process.
*
* @author Robin Chalas <[email protected]>
*/
class JWTDecodeFailureException extends JWTFailureException
{
const INVALID_TOKEN = 'invalid_token';
const UNVERIFIED_TOKEN = 'unverified_token';
const EXPIRED_TOKEN = 'expired_token';
}
4 changes: 3 additions & 1 deletion Exception/JWTEncodeFailureException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

/**
* Base class for exceptions thrown during JWTEncoderInterface::encode().
* JWTEncodeFailureException is thrown if an error occurs in the token encoding process.
*
* @author Robin Chalas <[email protected]>
*/
class JWTEncodeFailureException extends JWTFailureException
{
const INVALID_CONFIG = 'invalid_config';
const UNSIGNED_TOKEN = 'unsigned_token';
}
18 changes: 17 additions & 1 deletion Exception/JWTFailureException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@
class JWTFailureException extends \Exception
{
/**
* @var string
*/
private $reason;

/**
* @param string $reason
* @param string $message
* @param \Exception|null $previous
*/
public function __construct($message, \Exception $previous = null)
public function __construct($reason, $message, \Exception $previous = null)
{
$this->reason = $reason;

parent::__construct($message, 0, $previous);
}

/**
* @return string
*/
public function getReason()
{
return $this->reason;
}
}
21 changes: 21 additions & 0 deletions Exception/MissingTokenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

use Symfony\Component\Security\Core\Exception\AuthenticationException;

/**
* Exception to be thrown in case of invalid token during an authentication process.
*
* @author Robin Chalas <[email protected]>
*/
class MissingTokenException extends AuthenticationException
{
/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return 'JWT Token not found';
}
}
41 changes: 41 additions & 0 deletions Exception/UserNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Lexik\Bundle\JWTAuthenticationBundle\Exception;

use Symfony\Component\Security\Core\Exception\AuthenticationException;

/**
* User not found during authentication.
*
* @author Robin Chalas <[email protected]>
*/
class UserNotFoundException extends AuthenticationException
{
/**
* @var string
*/
private $userIdentityField;

/**
* @var string
*/
private $identity;

/**
* @param string $userIdentityField
* @param string $identity
*/
public function __construct($userIdentityField, $identity)
{
$this->userIdentityField = $userIdentityField;
$this->identity = $identity;
}

/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return sprintf('Unable to load an user with property "%s" = "%s". If the user identity has changed, you must renew the token. Otherwise, verify that the "lexik_jwt_authentication.user_identity_field" config option is correctly set.', $this->userIdentityField, $this->identity);
}
}
2 changes: 2 additions & 0 deletions LexikJWTAuthenticationBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public function build(ContainerBuilder $container)

/** @var SecurityExtension $extension */
$extension = $container->getExtension('security');

// BC 1.x
$extension->addSecurityListenerFactory(new JWTFactory());
}
}
Loading