diff --git a/README.md b/README.md index b0331d2c..58faccd1 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ $resource = LTI\LTI_Deep_Link_Resource::new() Everything is set to return the resource to the platform. There are two methods of doing this. -The following method will output the html for an aut-posting form for you. +The following method will output the html for an auto-posting form for you. ```php $dl->output_response_form([$resource]); ``` @@ -209,6 +209,12 @@ Alternatively you can just request the signed JWT that will need posting back to $dl->get_response_jwt([$resource]); ``` +If you've created a JWKS endpoint with `LTI\JWKS_Endpoint::new()`, the kid used in the endpoint can be provided as an additional parameter. +```php +$dl->get_response_jwt([$resource], 'a_unique_KID'); + +``` + ## Calling Services ### Names and Roles Service diff --git a/src/lti/LTI_Deep_Link.php b/src/lti/LTI_Deep_Link.php index c87cb0da..06631a04 100644 --- a/src/lti/LTI_Deep_Link.php +++ b/src/lti/LTI_Deep_Link.php @@ -14,10 +14,10 @@ public function __construct($registration, $deployment_id, $deep_link_settings) $this->deep_link_settings = $deep_link_settings; } - public function get_response_jwt($resources) { + public function get_response_jwt($resources, string $kid = null) { $message_jwt = [ "iss" => $this->registration->get_client_id(), - "aud" => [$this->registration->get_issuer()], + "aud" => $this->registration->get_issuer(), "exp" => time() + 600, "iat" => time(), "nonce" => 'nonce' . hash('sha256', random_bytes(64)), @@ -27,11 +27,17 @@ public function get_response_jwt($resources) { "https://purl.imsglobal.org/spec/lti-dl/claim/content_items" => array_map(function($resource) { return $resource->to_array(); }, $resources), "https://purl.imsglobal.org/spec/lti-dl/claim/data" => $this->deep_link_settings['data'], ]; - return JWT::encode($message_jwt, $this->registration->get_tool_private_key(), 'RS256', $this->registration->get_kid()); + + return JWT::encode( + $message_jwt, + $this->registration->get_tool_private_key(), + 'RS256', + is_null($kid) ? $this->registration->get_kid() : $kid + ); } - public function output_response_form($resources) { - $jwt = $this->get_response_jwt($resources); + public function output_response_form($resources, string $kid = null) { + $jwt = $this->get_response_jwt($resources, $kid); ?>
diff --git a/src/lti/LTI_Deep_Link_Resource.php b/src/lti/LTI_Deep_Link_Resource.php index 8abeadd6..b9215275 100644 --- a/src/lti/LTI_Deep_Link_Resource.php +++ b/src/lti/LTI_Deep_Link_Resource.php @@ -76,8 +76,11 @@ public function to_array() { "presentation" => [ "documentTarget" => $this->target, ], - "custom" => $this->custom_params, ]; + if (count($this->custom_params) > 0) { + $resource["custom"] = $this->custom_params; + } + if ($this->lineitem !== null) { $resource["lineItem"] = [ "scoreMaximum" => $this->lineitem->get_score_maximum(), diff --git a/src/lti/LTI_Message_Launch.php b/src/lti/LTI_Message_Launch.php index 7a18195d..4997a700 100644 --- a/src/lti/LTI_Message_Launch.php +++ b/src/lti/LTI_Message_Launch.php @@ -3,6 +3,7 @@ use Firebase\JWT\JWK; use Firebase\JWT\JWT; +use Firebase\JWT\Key; JWT::$leeway = 5; @@ -220,7 +221,7 @@ private function get_public_key() { foreach ($public_key_set['keys'] as $key) { if ($key['kid'] == $this->jwt['header']['kid']) { try { - return openssl_pkey_get_details(JWK::parseKey($key)); + return openssl_pkey_get_details(JWK::parseKey($key, 'RS256')->getKeyMaterial()); } catch(\Exception $e) { return false; } @@ -299,7 +300,7 @@ private function validate_jwt_signature() { // Validate JWT signature try { - JWT::decode($this->request['id_token'], $public_key['key'], array('RS256')); + JWT::decode($this->request['id_token'], new Key($public_key['key'], 'RS256')); } catch(\Exception $e) { var_dump($e); // Error validating signature.