ページ内コンテンツ
Hack for Moodle - LTI
iframe を使用すると,chrome, edgeでは 405 : Method Not Allowed が返される件
- SameSite=Lax であるため,iframe 使用時は Moodleのホストと JupyterHub のホストが異なる場合は,cookie が送信されない.
ソースコード トレース (数字はトレース順)
- ltiauthenticator/lti11/auth.py
- 0. authenticate()
- jupyterhub/handlers/base.py
- 4. login_user() self.current_user -> None
- 5. self.get_current_user_cookie()
- 6. self._user_for_cookie() cookie_id-> None cookie_name=jupyterhub-hub-login
- tornado/web.py
- 1. _unimplemented_method() HTTPError(405) を返す
- 2. wrapper() で 302 が返る.通常なら 200 が返るはず.
- 3. self.current_user -> None
- 7. get_secure_cookie() 結局,jupyterhub-hub-login のクッキーありません.(Webブラウザから送信されていません)
Moodle ホスト上で,JupyterHub へ接続するための feserver を動かしてみる.
- cookie が送信されない理由について推測が正しいならば,MoodleとJupyterHubを同じホストで動かせば(若しくは動いているように見せれば),iframeは問題なく使用できるはず.
- feserver のSSLのサーバ証明書で手こずったが,Apacheで使用している証明書使用したところ上手く繋がった.
- chrome, edge でも iframe の埋め込みが問題なく動作.
- でも問題点を確認したのみで,解決にはなっていない.
- 問題点: Moodleと JupyterHubを別のホストで動かすと,iframe を使用した場合,chrome, edge から cookieが送信されない.(その内 FireFoxもだよね)
解決方法
c.JupyterHub.tornado_settings = { "headers":{ "Content-Security-Policy": "frame-ancestors 'self' https://www.nsl.tuis.ac.jp" }, "cookie_options": {"SameSite": "None", "Secure": True } }
c.Spawner.args = ['--NotebookApp.tornado_settings={ "headers":{"Content-Security-Policy": "frame-ancestors \'self\' https://www.nsl.tuis.ac.jp" }, "cookie_options": { "SameSite": "None", "Secure": True } }' ]
参考:DB
MariaDB [moodle_db]> show columns from mdl_lti; +-------------------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------------------+--------------+------+-----+---------+----------------+ | id | bigint(10) | NO | PRI | NULL | auto_increment | | course | bigint(10) | NO | MUL | 0 | | | name | varchar(255) | NO | | | | | intro | longtext | YES | | NULL | | | introformat | smallint(4) | YES | | 0 | | | timecreated | bigint(10) | NO | | 0 | | | timemodified | bigint(10) | NO | | 0 | | | typeid | bigint(10) | YES | | NULL | | | toolurl | longtext | NO | | NULL | | | securetoolurl | longtext | YES | | NULL | | | instructorchoicesendname | tinyint(1) | YES | | NULL | | | instructorchoicesendemailaddr | tinyint(1) | YES | | NULL | | | instructorchoiceallowroster | tinyint(1) | YES | | NULL | | | instructorchoiceallowsetting | tinyint(1) | YES | | NULL | | | instructorcustomparameters | longtext | YES | | NULL | | | instructorchoiceacceptgrades | tinyint(1) | YES | | NULL | | | grade | bigint(10) | NO | | 100 | | | launchcontainer | tinyint(2) | NO | | 1 | | | resourcekey | varchar(255) | YES | | NULL | | | password | varchar(255) | YES | | NULL | | | debuglaunch | tinyint(1) | NO | | 0 | | | showtitlelaunch | tinyint(1) | NO | | 0 | | | showdescriptionlaunch | tinyint(1) | NO | | 0 | | | servicesalt | varchar(40) | YES | | NULL | | | icon | longtext | YES | | NULL | | | secureicon | longtext | YES | | NULL | | +-------------------------------+--------------+------+-----+---------+----------------+
<option value="1" selected="">デフォルト</option> <option value="2">埋め込み</option> <option value="3">埋め込み (ブロックなし)</option> <option value="5">既存のウィンドウ</option> <option value="4">新しいウィンドウ</option>
JupyterHub の Swapner での LTI 情報の受け取り処理
- jupyterhub_config.py
import os os.environ['JUPYTERHUB_CRYPT_KEY'] = 'c283a5e73c8f74cdc8c6fef5415f1c97948a5a5450b5dc7524b9939093a2bd1d' ....... ....... def userdata_hook(self, auth_state): print("AURTH") print(auth_state) ....... ....... c.Spawner.auth_state_hook = ProjectDockerSpawner.userdata_hook c.Authenticator.enable_auth_state = True
- 環境変数 JUPYTERHUB_CRYPT_KEY の設定が必要
- キーは openssl rand -hex 32 で生成(Moodle側と一致させる)
JupyterHub へのパラメータ送信
- Moodleの外部ツールの設定で,「一般」の「さらに表示する」でカスタムパラメータを指定すると,JupyterHub に任意のパラメータを送れる.
- XXX=ZZZ と入力すると,上記方法で {'costom_xxx': 'ZZZ'} として受け取れる(キーは小文字化される).
- # - などの特殊文字は _ になる.snake_case と言うらしい.
- 予約語
- next=
- next=
JupyterHub が Moodle から受け取ったデータ
- 一般的に認証モジュールが引数として受け取る値
{ 'user_id': '2', 'lis_person_sourcedid': '', 'roles': 'Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator', 'context_id': '98', 'context_label': 'JupyterHub-devel', 'context_title': 'JupyterHub 開発', 'resource_link_title': 'JupyterHub', 'resource_link_description': '', 'resource_link_id': '11', 'context_type': 'CourseSection', 'lis_course_section_sourcedid': '', 'lis_result_sourcedid': '{ "data":{ "instanceid":"11", "userid":"2", "typeid":"2", "launchid":1442412989 }, "hash":"a526aa576887b4dc19c16107e9ac7b0dbc92f852e23f044d55356ba83f3b7037" }', 'lis_outcome_service_url': 'https://el.mml.tuis.ac.jp/moodle/mod/lti/service.php', 'lis_person_name_given': 'Admin', 'lis_person_name_family': '管理ユーザ', 'lis_person_name_full': 'Admin 管理ユーザ', 'ext_user_username': 'admin', 'lis_person_contact_email_primary': 'fumi.hax@gmail.com', 'launch_presentation_locale': 'ja', 'ext_lms': 'moodle-2', 'tool_consumer_info_product_family_code': 'moodle', 'tool_consumer_info_version': '2020110902', 'lti_version': 'LTI-1p0', 'lti_message_type': 'basic-lti-launch-request', 'tool_consumer_instance_guid': '5384b0f81508b987c188b1985f5cd4e0', 'tool_consumer_instance_name': 'EL MML', 'tool_consumer_instance_description': 'e-Learning of MML', 'custom_mdl_user': '*', 'custom_mdl_teacher': 'iseki, admin', 'custom_mdl_image': 'jupyterhub/singleuser-mdl2 : latest', 'custom_mdl_suburl': '', 'custom_mdl_sessioninfo': '3,11', 'custom_mdl_vol_zzzz': '課題2', 'custom_mdl_vol_iseki': 'へへへ', 'custom_mdl_vol_jogrid': 'へへへ', 'custom_mdl_vol_': 'えええええええ', 'custom_mdl_vol_hhhhhggjjj': 'あああ', 'custom_mdl_vol_xxxx': 'いいいい', 'custom_mdl_sub_xxxx': '課題提出場所', 'custom_md_teacher': 'iseki', 'custom_ssss': '777', 'custom_zzzz': '', 'launch_presentation_document_target': 'window', 'launch_presentation_return_url': 'https://el.mml.tuis.ac.jp/moodle/mod/lti/return.php?course=98&launch_container=4&instanceid=11&sesskey=6wL3CYeL7Z' }
LTIの typeid (External Tool 情報) を格納するテーブル
MariaDB [moodle_db]> select id, name,baseurl,tooldomain,state,course,clientid from mdl_lti_types ; +----+------------------+----------------------------------------------------+-----------------------------+-------+--------+-----------------+ | id | name | baseurl | tooldomain | state | course | clientid | +----+------------------+----------------------------------------------------+-----------------------------+-------+--------+-----------------+ | 3 | antares:443 | https://antares.nsl.tuis.ac.jp/hub/lti/launch | antares.nsl.tuis.ac.jp | 1 | 1 | Oh9MyHxutcfbvhA | | 4 | GITLAB:FE 8100 | https://gitlab.nsl.tuis.ac.jp:8100/hub/lti/launch | gitlab.nsl.tuis.ac.jp:8100 | 1 | 1 | NULL | | 10 | procyon:443 | https://jupyterhub.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub.nsl.tuis.ac.jp | 1 | 1 | NULL | | 12 | JupyterHub00:443 | https://jupyterhub00.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub00.nsl.tuis.ac.jp | 1 | 1 | NULL | | 13 | JupyterHub01:443 | https://jupyterhub01.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub01.nsl.tuis.ac.jp | 1 | 1 | NULL | | 14 | JupyterHub02:443 | https://jupyterhub02.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub02.nsl.tuis.ac.jp | 1 | 1 | NULL | | 15 | JupyterHub03:443 | https://jupyterhub03.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub03.nsl.tuis.ac.jp | 1 | 1 | NULL | | 19 | antares:8000 | https://antares.nsl.tuis.ac.jp:8000/hub/lti/launch | antares.nsl.tuis.ac.jp:8000 | 1 | 1 | NULL | | 20 | aldebaran:443 | https://aldebaran.nsl.tuis.ac.jp/hub/lti/launch | aldebaran.nsl.tuis.ac.jp | 1 | 1 | NULL | +----+------------------+----------------------------------------------------+-----------------------------+-------+--------+-----------------+
- tooldomain は baseurl から抽出したようだ.
- clientid ???
Counter: 721,
today: 1,
yesterday: 0
最終更新: 2023-04-24 (月) 00:29:00 (JST) (510d) by iseki