Skip to content

Migration from 3.x to 4.x

Jonathan VUILLEMIN edited this page Feb 13, 2021 · 63 revisions

Table of contents

New features

You can find below the list of new features offered by version 4.x.

PHP 8 support

Version 4.x refreshed it's 3rd party libraries dependencies to provide PHP 8 compatibility, but also kept PHP 7.2 as minimal version to still allow this library usage in legacy systems.

See dependencies list for details.

New algorithms support

Version 4.x allows now usage of keys with following security algorithms:

  • RS256/384/512
  • HS256/384/512
  • ES256/384/512

Also, to allow more flexibility, the KeyInterface has been created, to configure the security algorithm (by default RS256) per declared key (not on the whole application anymore).

New JWT handling

Before version 4.x, the library relied directly on lcobucci/jwt 3rd party library for JWT handling.

Now, version 4.x provides an abstration layer to work with JWT (to avoid breaking changes risks on 3rd party library update), built on top of those new interfaces:

You can find an usage example of those components in the library JWT flow integration test.

In version 4.x, top level compoments (LTI launch builders & validators for messages and services) now rely on those interfaces, and use by default implementations provided by the library, to avoid breaking changes in your code

Breaking changes

Globally, top level classes of the library and their usage did not change, ensuring the migration to the version 4.x to be straightforward.

But version 4.x introduce some breaking changes on lower layers, as decribed below.

Security keys handling

Providing security keys to the library changed from:

<?php

use OAT\Library\Lti1p3Core\Security\Key\KeyChain;

$keyChain = new KeyChain(
    '1',                                // [required] identifier (used for JWT kid header)
    'mySetName',                        // [required] key set name (for grouping)
    'file://home/user/.ssh/id_rsa.pub', // [required] public key (file or content)
    'file://home/user/.ssh/id_rsa',     // [optional] private key (file or content)
    'test'                              // [optional] private key passphrase (if existing)
);

to:

<?php

use OAT\Library\Lti1p3Core\Security\Key\KeyChainFactory;
use OAT\Library\Lti1p3Core\Security\Key\KeyInterface;

$keyChain = (new KeyChainFactory)->create(
    '1',                                // [required] identifier (used for JWT kid header)
    'mySetName',                        // [required] key set name (for grouping)
    'file://home/user/.ssh/id_rsa.pub', // [required] public key (file or content)
     KeyInterface::DEFAULT_ALGORITHM,   // [optional] public key algorithm (default: RS256)
    'file://home/user/.ssh/id_rsa',     // [optional] private key (file or content)
    'test',                             // [optional] private key passphrase (if existing)
     KeyInterface::DEFAULT_ALGORITHM    // [optional] private key algorithm (default: RS256)
);

LTI messages and payloads handling

Version 4.x introduced the usage of collections, and applied those to, among others, LTI messages and payloads components.

Therefore manipulating LTI messages changed from:

<?php

use OAT\Library\Lti1p3Core\Message\LtiMessageInterface;

/** @var LtiMessageInterface $message */
$message->getParameters();                       // returns array of parameters
$message->hasParameter('something');             // returns bool
$message->getParameter('something', 'default');  // returns parameter value or 'default'
$message->getMandatoryParameter('something');    // throws exception when not found

to:

<?php

use OAT\Library\Lti1p3Core\Message\LtiMessageInterface;

/** @var LtiMessageInterface $message */
$message->getParameters();                               // returns CollectionInterface (iterable)
$message->getParameters()->all();                        // returns array of parameters
$message->getParameters()->count();                      // returns number of parameters
$message->getParameters()->has('something');             // returns bool
$message->getParameters()->get('something', 'default');  // returns parameter value or 'default'
$message->getParameters()->getMandatory('something');    // throws exception when not found

And manipulating LTI message payload tokens changed from:

<?php

use OAT\Library\Lti1p3Core\Message\Payload\LtiMessagePayloadInterface;

/** @var LtiMessagePayloadInterface $payload */
$payload->getToken()->getClaims();              // returns array of claims
$payload->getToken()->hasClaim('something');    // returns bool
$payload->getToken()->getClaim('something');    // returns claim value or thow exception when not found

to:

<?php

use OAT\Library\Lti1p3Core\Message\Payload\LtiMessagePayloadInterface;

/** @var LtiMessagePayloadInterface $payload */
$payload->getToken()->getClaims();                              // returns CollectionInterface (iterable)
$payload->getToken()->getClaims()->all();                       // returns array of claims
$payload->getToken()->getClaims()->count();                     // returns number of claims
$payload->getToken()->getClaims()->has('something');            // returns bool
$payload->getToken()->getClaims()->get('something', 'default'); // returns claim value or 'default'
$payload->getToken()->getClaims()->getMandatory('something');   // throws exception when not found

// token headers are also available as collection
$payload->getToken()->getHeaders()->all();                      // returns array of headers
$payload->getToken()->getHeaders()->count();                    // returns number of headers
$payload->getToken()->getHeaders()->has('something');           // returns bool
...
Clone this wiki locally