iframe を使用すると,chrome, edgeでは 405 : Method Not Allowed が返される件†[edit]
- SameSite=Lax であるため,iframe 使用時は Moodleのホストと JupyterHub のホストが異なる場合は,cookie が送信されない.
JupyterHub の log†[edit]
- 返されたステータス
- 302 POST
- 302 GET (通常はここで 200が返る)
- 302 GET
- 405 GET
ソースコード トレース (数字はトレース順)†[edit]
- ltiauthenticator/lti11/auth.py
- 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 を動かしてみる.†[edit]
- 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 }
}'
]
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_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 へのパラメータ送信†[edit]
- Moodleの外部ツールの設定で,「一般」の「さらに表示する」でカスタムパラメータを指定すると,JupyterHub に任意のパラメータを送れる.
- XXX=ZZZ と入力すると,上記方法で {'costom_xxx': 'ZZZ'} として受け取れる(キーは小文字化される).
- # - などの特殊文字は _ になる.snake_case と言うらしい.
- 一般的に認証モジュールが引数として受け取る値
{
'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'
}
Moodle DB†[edit]
LTIの typeid (External Tool 情報) を格納するテーブル†[edit]
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 ???