1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LTI詳細編 ④LTI Coreの通信フロー

Last updated at Posted at 2024-10-09

はじめに

LTIとはLearning Tools Interoperability(学習ツールの相互運用性)の略称であり、LMS(学習管理システム)を始めとする学習用プラットフォームと教材・学習ツールを連携させるための国際技術標準です。
教育関連のシステムやアプリケーションの利用者、導入者、開発・提供者それぞれにとってLTIを活用することには様々なメリットがあります。
今回はLTIの概要・詳細について、次の4つの記事を作成しました。
LTI基礎編
記事①LTIの基本
記事②利用の流れ(連携初期設定~ツール呼び出しまで)
記事③押さえておきたいキーワード

LTI詳細編
記事④LTI Coreの通信フロー ⇒ 本記事

本記事は4つ目のLTI詳細編④LTI Coreの通信フローになります。
ここでは、ツールを起動するまでに行われている各処理について、詳細に説明していきます。

※本記事では、次の用語は以下の内容を指しています。

  • LTI ⇒ LTI 1.3
  • プラットフォーム ⇒ LMS
    ※一般的には、LMSがプラットフォームになることが多いですが、必ずしもLMSである必要はありません。
  • ツール ⇒ 教材や学習コンテンツなどの学習ツール

1. LTI Coreについて

LTI CoreとはLTIの基礎部分を構成する仕様のことで、シングルサインオン(SSO)やツールとの連携といったLTIの基本となる機能を提供します。これを拡張したものがLTI概要編①LTIの基本 1.3章で説明しているLTI Advantageになります。

2. LTI Core通信フローの詳細

LTI概要編の記事で少し触れたように、LTIの認証はOpenID Connect(OIDC)がベースになっています。
以下の図は、LTI Core(ResourceLinkRequest)によるツール起動までのフローを表した図になります。
image.png

プラットフォームからツールを起動するまでのフローは、大きく3つのパートに分けられます。

  1. OIDC①(Platform⇒Tool)
    プラットフォームからツールを起動する際、最初にツールのInitiate Login URLにアクセスしてOIDC認証を開始します。
    (※LTIではプラットフォームがIDプロバイダーの役割を果たすことが多く、プラットフォームが起点となってフローが始まるため、このパートはOIDCにおける4. Initiating Login from a Third Partyにあたります。)

  2. OIDC②(Tool⇒Platform)
    プラットフォームはツールから送信された情報を使用してツールの認証を行います。認証に成功した場合、プラットフォームはログインしているユーザーの情報などを含むIDトークンを発行します。

  3. ResourceLinkRequest(Platform⇒Tool)
    プラットフォームは発行したIDトークンをツールに送り、ツールは受け取ったIDトークンの検証を行います。検証が完了すると、目的のツール画面が表示されます。

次の章からは、それぞれのパートの処理や必要となる情報などについて詳細に説明していきます。

2.1. OIDC①(Platform⇒Tool)

まずは、LTIによる認証を開始する際の処理について説明します。
この処理は、ユーザーがプラットフォーム上に設置されているLTIリンクからツールを起動しようとした際に、最初に行われる処理です。
ユーザーがLTIリンクをクリックすると、プラットフォームはUA(ユーザーエージェント)をツールのログインエンドポイント(記事②4章の①Tool OIDC Login Initiation URL)にリダイレクトさせることによって、OIDCフローを開始します。リクエストの形式はGET/POSTのどちらでも問題ありません。
このリクエストに含まれているパラメーターについては、次のようなものがあります。
(※本記事の表について、黒字で記載しているのはOIDCで定義されているもの、赤字で記載しているのはLTIで追加されたものになります。)

パラメーター 必須/任意  概要
iss 必須 プラットフォームを識別するための値
login_hint 必須 ユーザーがログイン時に使用するログイン識別子のヒント
(例)ユーザーのUUID、ログインIDなど
target_link_uri 必須 LTI通信フローの最後に実行される実際のエンドポイント
lti_deployment_id 任意 これを含む場合、後続のLTIメッセージのクレーム[*注1]で渡されるのと同じデプロイメントID[*注2]にする必要がある
client_id 任意 後続のLTIメッセージリクエストの認可に使用されるクライアントID[*注3]を指定するための値
lti_message_hint 任意 起動される実際のメッセージを特定するLTI固有のパラメーターで、これを含む場合は後続の認証リクエストにも同じ値を含める必要がある

*注1:https://purl.imsglobal.org/spec/lti/claim/deployment_id を指し、詳細については後述します。
*注2:デプロイメントIDについては、こちらを参照してください。
*注3:クライアントIDについては、こちらを参照してください。

2.2. OIDC②(Tool⇒Platform)

認証リクエスト

次に、ツールはOIDC①で送られてきた情報を基にリクエストを作成し、UAをプラットフォームの認証エンドポイント(記事②4章の②Platform OIDC Auth URL)にリダイレクトさせます。リクエストの形式はOIDC①と同様でGET/POSTのどちらでも問題ありません。
この認証リクエストに含まれているパラメーターには、次のようなものがあります。

パラメーター 必須/任意  概要
scope 必須 アクセストークンに紐づくアクセス権を指定する値であるが、OIDCの場合はopenid(固定値)
reponse_type 必須 使用される認可フローを決定するための値で、ここではid_token(固定値)
client_id 必須 プラットフォームがツールを識別するための値
redirect_uri 必須 プラットフォームで発行されたIDトークンの受け渡し先となるツールのエンドポイントを指定するための値
login_hint 必須 OIDC①のlogin_hintで渡されたものと同じ値
state 任意 ユーザーのセッションと紐づけて管理することでCSRFを防止するための値
response_mode 必須 トークンは長くなる可能性があり、POSTとして渡す必要があるため、ここではform_post(固定値)
nonce 必須 ここで指定した値がIDトークン中のnonceにも記載され、認証リクエストと対応するIDトークンであることを証明することで、リプレイ攻撃を防止するための値
prompt 必須 プラットフォームに対してUIの動作を指定するための値で、ここではnone(固定値)
lti_message_hint 任意[*注4] OIDC①のlti_message_hintで渡されたものと同じ値

*注4:OIDC①のパラメーターにlti_message_hintが含まれている場合は必須になります。

認証リクエストの検証

認証リクエストを受けたプラットフォームは、そのリクエストが正当なものであるかの検証を行います。認証リクエストに含まれるパラメーターを基に、プラットフォームはredirect_uriがclient_idで示されたツールの有効なエンドポイントであるか、現在ログインしているユーザーがlogin_hintと一致するかを検証した後、IDトークンを発行します。
IDトークンとはツールがユーザーの認証を行うために使うものです。このIDトークンには、ユーザーを識別するためのIDなど始めとして様々な情報が含まれているとともに、改ざんを防止するための署名がされています。この署名にはプラットフォームの秘密鍵が使われます。

2.3. ResourceLinkRequest(Platform⇒Tool)

認証レスポンス

最後に、UAをOIDC②で指定されたredirect_uriにリダイレクトさせ、認証レスポンスで発行したIDトークンをツールに送ります。このときの認証レスポンスはPOSTで送る必要があり、含まれているパラメーターは次のようになっています。

パラメーター 必須/任意  概要
state 必須 ツールはこの値がOIDC②で送ったstateと一致することを確認する必要がある
id_token 必須 ユーザー認証に使う署名つきのJSON Web Token(JWT)

IDトークンについて

ここからは、認証レスポンスで受け取ったIDトークンの中身について説明していきます。IDトークンは表中に記載したようにJWTの形式になっており、JWTに含まれる項目はClaim(クレーム)と呼ばれます。JWTは「ヘッダー」「ペイロード」「署名」の3パートから構成されており、それぞれのパートは.(ドット)で区切られ、それをBase64 URLエンコードした文字列になっています。ここからはそれぞれのパートについて説明していきます。

ヘッダー

ヘッダー部分には、次のようなクレームが含まれており、これらは後の署名検証に使用されます。

クレーム 必須/任意  概要
typ 必須 トークンの形式を示す値で、ここではJWT(固定値)
alg 必須 署名に使われているアルゴリズムを示す値[*注5]
kid 任意 プラットフォームの公開鍵のID

*注5:こちらで記載されているアルゴリズムのいずれかを使用する必要があります。

署名

実際のJWTの中身とは順序が前後しますが、先に署名部分について説明します。
(※実際のJWTは「ヘッダー」.「ペイロード」.「署名」の順番になっています。)
名前の通り、署名部分にはヘッダーのalgクレームで指定されたアルゴリズムを使って作成した署名が入っています。ツールは、ヘッダーのkidクレームで指定されたIDを使ってプラットフォームの公開鍵を取得し、署名の検証を行います。

ペイロード

ペイロード部分には、ユーザーを識別するための情報やIDトークンの正当性を確認するための情報など、重要なクレームが多く含まれています。具体的には次のようなクレームがあります。
(※ここに記載したのは代表的なものだけで、これ以外にもOIDCやLTIで定義されているクレームがあります。)

クレーム 必須/任意  概要
iss 必須 IDトークンの発行者であるプラットフォームを識別するための値
aud 必須 IDトークンを受け取るツールのクライアントID
sub 必須 ユーザーを識別するための値
exp 必須 IDトークンの有効期限
iat 必須 IDトークンの発行時刻
nonce 必須 OIDC②に含まれるnonceと同じ値
azp 任意 認可対象のツールのクライアントID
name 任意 氏名
given_name 任意
family_name 任意
middle_name 任意 ミドルネーム
picture 任意 プロフィール画像のURL
email 任意 メールアドレス
message_type[*注6] 必須 LTIメッセージのタイプを示す値で、今回はLtiResourceLinkRequest(固定値)
version 必須 LTIのバージョンを示す値で、今回は1.3.0(固定値)
deployment_id 必須 デプロイメントID
target_link_uri 必須 OIDC①で指定されたtarget_link_uriと同じ値
resource_link 必須 3つのパラメーター(id[*注7], title, description)で構成されるリソースリンクのプロパティ
roles 必須 ユーザーが持つロールのURI値の配列[*注8]
context 任意 4つのパラメーター(id[*注9], type, label, title)から構成されるリソースリンクが設置されているコンテキストのプロパティ
tool_platform 任意 起動を開始するプラットフォームインスタンスに関連するプロパティ
role_scope_mentor 任意 ユーザーがメンターとしてアクセスできるユーザーID値の配列
launch_presentation 任意 どのようにコンテンツを表示するか(ウィンドウやフレームの種類、高さ/幅など)を指定するためのプロパティ
lis 任意 利用可能なLIS[*注10]に関するプロパティ
custom 任意 開発者が独自に追加することのできるkey-value形式のカスタムプロパティ

*注6:これ以降に記載するクレームは、実際にはhttps://purl.imsglobal.org/spec/lti/claim/ に続くURL形式で表現されますが、ここでは省略して記載しています。
(例)https://purl.imsglobal.org/spec/lti/claim/message_type
*注7:3つの中でidだけが必須のパラメーターであり、resource_link_idと呼ばれます。
*注8:こちらにLTIで使用されるロールの一覧が記載されており、この中から少なくとも1つのロールが含まれている必要があります。
*注9:4つの中でidだけが必須のパラメーターであり、context_idと呼ばれます。
*注10:学習情報サービス(Learning Information Service)の略称です。

IDトークンの検証

IDトークン中に含まれる情報と、ここまでのOIDC①・②の情報を基に、ツールはIDトークンの検証を行っていきます。具体的な検証内容[*注11]としては、次のようなものがあります。

  1. 署名の検証
    プラットフォームの公開鍵を使ってIDトークンの署名検証を行います。このとき、プラットフォームの公開鍵は記事② 2. 初期設定でツールに登録しておいたPlatform JWKS URLから取得します。

  2. 発行者の検証
    事前にツール側に登録されているプラットフォームのIssuer IDとIDトークン中のissの値が一致することを確認します。

  3. 受信者の検証
    IDトークン中ののaudがissで識別されるプラットフォームで発行されたclient_idの値を含んでいることを確認します。

  4. 署名アルゴリズムの検証
    IDトークンのヘッダーに含まれるalgの値がこちらに記載されている承認されたアルゴリズムのいずれかであることを確認します。

  5. 有効期限の検証
    現在の時刻がIDトークン中のexpで表される時刻より前であることを確認します。

  6. リプレイ攻撃の検証
    OIDC②のnonceとIDトークン中のnonceの値が一致すること、まだこのnonceの値を受け取っていないことを確認します。

*注11:記載している検証内容は、1EdTech Security Framework v1.1 #5.1.3 Authentication Response Validationから一部抜粋したものになります。

LTIリソースの表示

すべての検証が完了し、正しいIDトークンであることが証明されると、ツールはIDトークン中のtarget_link_uriで指定されたコンテンツの画面を表示し、一連の処理は完了となります。

以下の画像は、オープンソースのLMSであるMoodle(プラットフォーム)から1EdTechが公開しているブロック崩しゲーム(ツール)を起動したときのものです。プラットフォーム上にあるLTIリンクをクリックすると、本記事で説明した通信フローが実行され、すべての処理が問題なく終わるとツール画面が表示されます。
(※下記の画像では、「iframe」を使って同一Webページ内にツール画面を埋め込む形で起動していますが、新規ウィンドウ上で起動するように設定することも可能です。)
image.png
LTIによってSSOが実現されているため、ツール起動時に再度ID・PWを入力してログインする必要はありません。また、今回起動したツールではLTIによってプラットフォームからツールに連携された情報を基に、トップ画面にユーザー名が表示される仕様になっています。記事① 1章で説明しているように、これらがLTIを活用するメリットの一つになります。

参考資料

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?