Docker で検証用 CAS サーバ

CAS との連携を確認するのに、Docker でサクッと建てようと思ったら思いのほか手を焼いたのでメモ。

やりたいこと

CAS でSSOするサービス側モジュールの検査のために、とりあえずのCASサーバを立てて使いたい。細かい設定はいらない。

昔は仮想マシンに Tomcat 入れて動かしていましたが、今ならもう Docker でサクッと立つはず。。。

コンテナイメージの配布状況

本家のドキュメント、この素っ気なさからしていやな予感。

本家のコンテナイメージと、ビルドソース

いろいろ試した結果、配布されているコンテナイメージをそのまま何とか動かしても思ったように扱えない。

このコンテナイメージは SRC1 をビルドしたもので、SRC1 は gradle 実行環境と SRC2 をコンテナイメージの中に展開して gradle でビルドをしている。ただし、SRC1 は SRC2 のビルドオプションを最小限しか設定しておらず、実用性に難がある。

SRC2 が本命だが、SRC2 には gradle のビルド環境構築手続きが含まれていない。それを書くと結局は SRC1 を引っ張り出すことになるので、SRC1 を調整してカスタムイメージをビルドすることにする。

念のために Vagrant も探してみたけどいまいちでしたので、やっぱりコンテナのビルド。

予備知識、前提

はまりポイント、特に Java のビルド環境についてあまり経験の無い方は、ビルドオプションを調整するところかと思います(私がそうでした)。

ビルド環境の用意

まずは github.com/apereo/cas-webapp-docker をクローンしてビルドの準備をします。

git clone https://github.com/apereo/cas-webapp-docker.git
cd cas-webapp-docker
# git reset --hard a2d664fd006d86f0bb09d65c2ffb0eeb25018fdf

README.md の SSL セクションを実行します。ここはローカル開発用と割り切って、鍵もPASSもそのままです。

keytool -genkeypair -alias cas -keyalg RSA -keypass changeit \
        -storepass changeit -keystore ./thekeystore \
        -dname "CN=cas.example.org,OU=Example,OU=Org,C=AU" \
        -ext SAN="dns:example.org,dns:localhost,ip:127.0.0.1"

sudo su root -c " echo '127.0.0.1 cas.example.org' >> /etc/hosts"

実際に使うにはまだ設定が必要ですが、念のために一度ビルドして動かしてみます。

./build.sh 6.4
./run.sh 6.4

うまくいけば、コンソール出力に大きく「READY」と表示されます。(ここのコードブロックでの表示では形が崩れているかもしれません)。

2021-12-21 05:02:57,689 INFO [org.apereo.cas.web.CasWebApplication] - <>
2021-12-21 05:02:57,689 INFO [org.apereo.cas.web.CasWebApplication] - <

  ____  _____    _    ______   __
 |  _ \| ____|  / \  |  _ \ \ / /
 | |_) |  _|   / _ \ | | | \ V / 
 |  _ <| |___ / ___ \| |_| || |  
 |_| \_\_____/_/   \_\____/ |_|  

>
2021-12-21 05:02:57,689 INFO [org.apereo.cas.web.CasWebApplication] - <>
2021-12-21 05:20:05,860 INFO [org.apereo.cas.web.CasWebApplication] - <Ready to process requests @ [2021-12-21T05:20:05.859Z]>
2021-12-21 05:20:05,916 INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [InMemoryServiceRegistry].>

特に、コードブロックにコピーしたログの一番最後の行、 [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [InMemoryServiceRegistry].> というのがポイントです。これは、Application ServiceRegistry に登録がないよ、と言っています。後で改善します。

この状態でブラウザで https://cas.example.org:8443/cas/login を開くとログイン画面を表示できるはずですが、実際には証明書が INVALID なために警告が表示されてしまいます。以下のコマンドで証明書を吐き出して許可リストに加えるか、ブラウザで開いたときに強制的に表示させます。

keytool -export -alias cas -keystore thekeystore -rfc -file cas-self.cert

ログイン画面が表示されると、casuser アカウントで認証は成功するはずです。

アプリケーションサーバの連携確認

アプリケーションサーバにこのCASサーバを登録するには、以下を確認してください。

  • ブラウザは、CASサーバとアプリケーションサーバのどちらにもアクセスできること
  • アプリケーションサーバがこのCASサーバに 8443:tcp でアクセスできること
  • アプリケーションサーバの hosts ファイルにも cas.example.org を足しておくこと
  • アプリケーションサーバの CAS 連携モジュールは証明書チェックを無視する設定になっていること

特に、PHPのCURLについては以下の設定を使います。

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);

アプリケーションサーバでCAS認証しようとすると、CASサーバにリダイレクトされますが、以下の表示になると思います。

また、CASサーバのログでは試した直後には以下のログが出ているはずです。

2021-12-21 04:13:02,682 ERROR [org.apereo.cas.services.web.support.RegisteredServiceResponseHeadersEnforcementFilter] - <Service unauthorized>

つまり、許可サービスリストの登録が0で、いま試したアプリケーションサーバもはじかれている状態になります。

Docker のカスタマイズと Application ServiceRegistry の設定

ここからは、チェックアウトしているDocker のビルドキットをカスタマイズして、Application ServiceRegistry を設定し直したコンテナイメージを作り直していきます。

まずは2つファイルを新規追加します。1つは cas サーバの起動設定ファイルで、JSONリポジトリを有効に指定します。1つはテスト用アプリケーションサーバの定義ファイルで、http://192.168.56.??/ で動作することを前提としています。

etc/cas/config/cas.properties

cas.server.name=https://cas.example.org:8443
cas.server.prefix=${cas.server.name}/cas

logging.config=file:/etc/cas/config/log4j2.xml

# for json services ( need build option
cas.service-registry.core.init-from-json=true
cas.service-registry.json.watcher-enabled=true
cas.service-registry.json.location=file:/etc/cas/services
#cas.service-registry.yaml.location=file:/etc/cas/services

# cas.authn.accept.enabled=false

etc/cas/services/test-2.json

{
     "@class" : "org.apereo.cas.services.RegexRegisteredService",
            "id":2,
            "serviceId":"http://192.168.*",
            "name":"DEV",
            "description":"dev",
            "allowedToProxy":true,
            "enabled":true,
            "ssoEnabled":true,
            "anonymousAccess":false,
            "allowedAttributes":["uid", "mail"]
            "extraAttributes":{
                "someCustomAttribute":"Custom attribute value"
            },
            "evaluationOrder":2
}

続いて、gradle のビルド定義ファイルを置き換えます。ちょっと面倒なのですが、以下の build.grade ファイルを取得して、手元のファイルを置き換えてしまいます。

その上で、L930 くらいにある dependencies のセクションに ServiceRegistry の JOSN ストレージモジュールを足します。${project.'cas.version'} の変数も、このまま書きます。

dependencies {
    /**
     * CAS dependencies and modules may be listed here.
     *
     * ...
     */
     ...

    /* add */
    implementation "org.apereo.cas:cas-server-support-json-service-registry:${project.'cas.version'}"
}

続いて、Dockerfile を編集します。2カ所はファイルコピー操作を追加、gradle のビルドコマンドは、./gradlew dependencies コマンドを追加しています。2ステップに分解していますが、まとめてもかまいません。

FROM centos:centos7

MAINTAINER Apereo Foundation

ENV PATH=$PATH:$JRE_HOME/bin
ARG cas_version

RUN yum -y install wget tar unzip git \
    && yum -y clean all

# Download Azul Java, verify the hash, and install \
RUN set -x; \
    java_version=11.0.3; \
    zulu_version=11.31.11-ca; \
    java_hash=20218b15ae5ef1318aed1a3d5dde3219; \
    cd / \
    && wget http://cdn.azul.com/zulu/bin/zulu$zulu_version-jdk$java_version-linux_x64.tar.gz \
    && echo "$java_hash  zulu$zulu_version-jdk$java_version-linux_x64.tar.gz" | md5sum -c - \
    && tar -zxvf zulu$zulu_version-jdk$java_version-linux_x64.tar.gz -C /opt \
    && rm zulu$zulu_version-jdk$java_version-linux_x64.tar.gz \
    && ln -s /opt/zulu$zulu_version-jdk$java_version-linux_x64/ /opt/java-home;

# Download the CAS overlay project \
RUN cd / \
    && git clone --depth 1 --single-branch -b $cas_version https://github.com/apereo/cas-overlay-template.git cas-overlay \
    && mkdir -p /etc/cas \
    && mkdir -p cas-overlay/bin;

COPY thekeystore /etc/cas/
COPY bin/*.* cas-overlay/
COPY etc/cas/config/*.* /cas-overlay/etc/cas/config/
COPY etc/cas/services/*.* /cas-overlay/etc/cas/services/
# 追記
COPY build.gradle /cas-overlay/build.gradle

RUN chmod 750 cas-overlay/gradlew \
    && chmod 750 cas-overlay/*.sh \
    && chmod 750 /opt/java-home/bin/java;

EXPOSE 8080 8443

WORKDIR /cas-overlay

ENV JAVA_HOME /opt/java-home
ENV PATH $PATH:$JAVA_HOME/bin:.

# 書き換え
RUN mkdir -p ~/.gradle  && echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
RUN ./gradlew dependencies && ./gradlew clean build --parallel \
    && rm -rf /root/.gradle

# 追記
RUN mkdir -p /etc/cas/config && mkdir -p /etc/cas/services && cp etc/cas/config/* /etc/cas/config/ && cp etc/cas/services/* /etc/cas/services/

CMD ["/cas-overlay/run-cas.sh"]

あらためてビルドと実行を行います。

./build.sh 6.4
./run.sh 6.4

もし JSON のサービス定義ファイルをロードできていれば、「READY」の後に以下のログが出ます。 [org.apereo.cas.services.AbstractServicesManager] - <Loaded [1] service(s) from [JsonServiceRegistry].> となっていれば、JSON のアプリケーション定義をロードするのに成功しています。

2021-12-21 09:07:28,348 INFO [org.apereo.cas.web.CasWebApplication] - <Ready to process requests @ [2021-12-21T09:07:28.342Z]>
2021-12-21 09:07:28,780 INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [1] service(s) from [JsonServiceRegistry].>

アプリケーション定義ファイルのURL正規表現と、アプリケーションのURLがマッチしていれば、SSO認証したときに無事に CAS のログイン画面が表示されるはずです。パスワード認証に成功すると、CASサーバはチケットを発行してアプリケーションにリダイレクトします。ログは以下が残ります。

2021-12-21 09:39:39,055 INFO [org.apereo.cas.DefaultCentralAuthenticationService] - <Granted service ticket [ST-11-Li75-erdbw7sPZ5vdnW5QG1IcAY-66a57e874b0d] for service [http://192.168.56.76/login.php?auth_mode=CAS] and principal [casuser]>
2021-12-21 09:39:39,055 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: casuser
WHAT: {service=http://192.168.56.76/login.php?auth_mode=CAS, return=ST-11-Li75-erdbw7sPZ5vdnW5QG1IcAY-66a57e874b0d}
ACTION: SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Tue Dec 21 09:39:39 UTC 2021
CLIENT IP ADDRESS: 172.17.0.1
SERVER IP ADDRESS: 172.17.0.2
=============================================================

アプリケーションサーバがリダイレクトURLより認証チケットを受け取ると、アプリケーションサーバからCASサーバにチケットのValidationの問い合わせを行います。Validation に成功すると、CASサーバには以下のログが残り、アプリケーションサーバではユーザ名など属性情報を受け取ります。

2021-12-21 09:39:39,159 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: casuser
WHAT: {ticket=ST-11-Li75-erdbw7sPZ5vdnW5QG1IcAY-66a57e874b0d, service=http://192.168.56.76/login.php?auth_mode=CAS}
ACTION: SERVICE_TICKET_VALIDATE_SUCCESS
APPLICATION: CAS
WHEN: Tue Dec 21 09:39:39 UTC 2021
CLIENT IP ADDRESS: 172.17.0.1
SERVER IP ADDRESS: 172.17.0.2
=============================================================

今後

Java のビルドツールはあまり使ったことがないので、gradle の設定ファイルの記入位置を見つけるのに思いのほか時間がかかりました。

ですが、これですぐに検証サーバが用意できます。CASサーバのスタブを書くまでの間、クライアントのライブラリ更新やリファクタリングなどで頼もしく動いてくれるのを期待します。

遠隔会議ツールに関する追加情報

こんにちは。福岡です。

こちらでZoomsのLTI連携について調べて書きましたが、学校によっては別の遠隔会議ツールを使っており、質問いただいたり、情報提供をお願いしたりしている状況です。

だんだん整理してまとめていきますが、ひとまず今追加で調べたメモを書いておきます。

Zoom.us はURLを配布する手もあります。連携するメリットは?

・先生はわざわざZoomにログインし直すことなく、WebClassから直接Zoomの会議の管理ができます。WebClass上で他の資料を書いたり案内を書いたりしていて、ツールやアカウントの使い分けが発生しないので楽だと思います。
・WebClassのコースの単位で会議の管理ができます。コースを切り替えれば会議一覧は混じらないので、先生も学生もスケジュール確認しやすいと思います。

Zoom.us とLTI連携してみたんですが、画面が英語です。日本語になりませんか?

残念ながら、Zoom LTI Pro が英語しかまだサポートしていないようです。

Zoom LTI Pro の Release noteがこちらですが、このうち March 2020
(Current Release)の Known Issues の一番最後に記載があります。

https://zoomappdocs.docs.stoplight.io/lti-pro-v2/release-notes

”Changing to another language besides English is currently not supported”

Zoom.us で参加者の確認方法

WebClass経由で学生が会議に入ってくるとき、WebClassからは学生の氏名の情報を送っています。WebClass経由だとその名前が表示されると思いますが、確認中です。

後で参加者が誰だったか確認する場所は「Report」というリンクでありますが、有料プランでないと記録は残らないと思います。

Microsoft Teams と連携できますか?

Microsoft Teams との連携はまだ詳しいことはわかっておらず、WebClass との連携実績
もない状態です。

Microsoft Teams が LTI という教育システム向けの連携機能があるかどうか
については、断片的に手がかりを得ているのは以下となります。

Canvas は Microsoft Teams と連携できるようです。
[1] https://community.canvaslms.com/docs/DOC-18558-microsoft-teams-meetings-in-canvas

この記事で Canvas が Microsoft Teams との連携に使用しているのは、こちらで
提供されている開発ツールを使うようです。

[2] https://github.com/OfficeDev/msteams-app-lms-meetings

[1] によると [2] は LTI 1.3 という規格で連携するようです。
WebClass はLTI 1.1に対応していますが、1.3には対応していません。

[2]の詳細や、[2]がWebClassにも使えるものなのか、他にもやり方があるものなのか、まだ調査中です。

Zoom.us 教育機関アカウントとのLTI連携

ZoomのLMS機能について、以前個人アカウントでのWebClassとの連携について調べました。

https://webclass.jp/blog/2020/03/18/lti-integration-with-zoom-us/

今回、教育機関アカウントを使ってWebClassとのLTI連携したケースについて東京薬科大学様より報告をいただきましたので、共有いたします。

検証の手順

教育機関のライセンスについて

今、教育機関に向けてZoom.us では制限を解除しているようです。これは「マナトメプログラム」といいます。ただし、こちらの大学では契約に至るまでがけっこう時間がかかったそうで、契約対応件数が多いなど今の事情もあるかもしれません。

教育アカウントとして契約して、その管理者の配下でユーザを「基本」権限と「Licensed」権限のユーザを振り分けて利用します。「基本」権限だと個人契約と同じ利用制限で、「Licensed」権限だと制限が外れるとの理解です。グループ分けができますので、こちらでは学部等でグループを作成し、それぞれ代表者と設定して管理する予定です。

WebClassにLTI Keyの登録

Zoom.us から LTI 連携キーを発行してWebClassに登録する流れは基本的に事前の報告内容と同じです。契約アカウントより LTI キーを1つ発行して登録しました。

Zoom Marketplace LTI Pro
https://marketplace.zoom.us/apps/f8JUB3eeQv2lXsjKq5B2FA

・システム管理者として、「システム管理」>「LTIツール設定」を登録(基本は初期設定のまま)ツールの表示ON コース管理者によるURL設定OFF

コースでZoom.usに接続する教材の追加

・コース管理者Aが、「教材」>「LTIツール」で教材「Zoom接続テスト」を作成
  送信制限: 氏名OFF メールアドレスOFF (メールアドレスの送信は必須です)
・「Zoom接続テスト」で「Schedule a New Meeting」で会議を作成、その詳細を設定(基本は初期設定のまま)>「SAVE」
  Topic名:WebClass運用マニュアル(→コース名が入る)
  Registration OFF Video OFF Audio BOTH
  require meeting password ON Enable Waiting room ON

※ アカデミックで契約すると、管理者は機関メールアドレスをもつユーザに「基本」か「Licensed」の権限を与えることができますが今回の検証では「Licensed」のユーザで試しました。

教材を作成いただくと、このように1教材としてコースの教材一覧に加わります。

教材の実行

用意した教材を開くと、Zoom.us が提供する画面を表示できます。先生も学生も同じような画面ですが、先生の場合は会議を作成・編集するボタン等が追加で表示されます。

この画面では、コースに紐づいて複数のミーティングを作成できます。授業回ごとに作成するなどできます。

上記のように、会議の作成画面では日時もスケジュールできます。

検証によりわかったこと

会議の作成者ができる先生について

DP 社内で個人アカウントでLTIキーを生成して実験したときは、キーを生成したZoomアカウントのメールアドレスを持った先生でないと、会議の作成ができませんでした。しかし今回確認いただいたように、教育アカウントでLTIキーを登録していると、Licensed に設定されているアカウントの先生であれば先生の単位でLTIキーの発行などをしなくてもこうして会議の作成ができるようです。

コースに複数の先生がいるとき

コース管理者が複数いる場合いずれのコース管理者も会議を作成することができます。基本的には会議のホストは作成者のみであり、会議のStartとDeleteができるのも作成者のみです。作成の段階で他のコース管理者をAlternativeホストに指定することもできますが、AlternativeホストはStartの権限しかなく設定を変えたりDeleteすることはできないようです。またAlternativeホストには招待メールが送られます。(検証を通してその他のメールが送られることはありませんでした。)

先ほどの検証コースでは、それぞれの先生方は以下のようになります。

・WebClassコース管理者Aは「Start」「Delete」、ユーザーは「Join」が表示される。
・教材作成者が指定したメールアドレスをもつユーザBは「Start]のみが表示される。
・教材作成者が指定しなかったコース管理者Cでは「Join」のみが表示される。

複数の会議を作りたい場合

Zoomの管理者画面では教材名ではなくTopic名がリストされます。コース内にLTI教材を複数作っても意味がなく、同じミーティングリストが表示されるため、コース内でアクセスする学生を制限したい場合には別途URLを記載した教材を作る必要がありそうです。

課題

WebClassから会議に参加する際に、もともと別人のアカウントでZoomにログインしていた場合そちらの設定で会議に参加してしまうようです。この不具合はログアウトしてブラウザを再起動すれば解決されましたが、参加履歴を出席代わりにしたい時には問題になる可能性があります。

また、あるマシンでWindows10/IEで試したところ401エラーが出てZoomを開けませんでした。Edgeではアクセスできたのですが原因は不明です。

LTI integration with Zoom.us

こんにちは。福岡です

コロナウイルスの対応のため、日本の大学でも4月の授業スタートについて検討が進められていると思います。もし学生を集めて授業ができなくなったとき、遠隔の授業で対応できないか検討されているところもあると思います。

ここではテレビ会議等のためのサービスをWebClassと連携させて使う方法として、まずは Zoom.us Meeting について今調べてわかっていることを書きます。

ここ数年の間にノートパソコンやスマホでテレビ会議をすることも多くなりました。少人数での会議だけでなく、3月の国内の学会ではこのようなテレビ会議を利用して数十人で実施したケースもあったようです。テレビ会議ソフトはツールとして比較的手軽に使えるようになっているだけでなく、「あとで見直せるように動画で保存しなきゃ」と構えることなく会議だけして保存せずに終了するあたり、気持ちの上でも楽だと思います。

ほかに Cisco Webex Meetings などもありますが、調査が進み次第投稿します。

Zoom.us Meeting

License
https://zoom.nissho-ele.co.jp/lineup/zoom_meeting/

Zooms for Education
https://zoom.us/education

Basic(無料)プランでは配信時間40分の制限と参加人数100人の制限があります。今は4/30までのあいだ、教育機関向けに制限を開放しているようです。

ここでは、急ぎ調査した都合上、教育機関アカウントではなく個人のアカウントで Basicプランで試してみました。設定操作方法の基本的なところは同じと思いますが、実際に教育機関でアカウント取得して設定される際には、差異があると思います。

連携せずに使う

先生と学生がそれぞれ個人のZoomアカウントを持っていれば、先生が会議をホストし、案内用のURLをWebClassのコースで学生に伝えることで会議できます。

例えば講義回ごとに資料教材として会議URLを案内すると、整理もできると思います。
もしくは、教材が多い場合は「タイムライン」を使っていただくと、今見て欲しい教材・URLが学生に伝わりやすいと思います。

WebClass上では出席機能や、その他資料を配布する機能、掲示板等があります。説明をZoomでしつつ、これらWebClassのコーツツールで補ってもらうことができると思います。

LMS との連携

Zoom.usのLMS連携機能を使うとどういうことができるかを調べています。

Zooms.us で LTI Key の発行

Zoom.us は LTI に対応しています。LTI連携を使用するには、Zoomsの Web でサインインし、マーケットプレイスからLTIモジュールを有効化します。

マーケットプレイス
https://marketplace.zoom.us

マーケットプレイス - LTI pro
https://marketplace.zoom.us/apps/f8JUB3eeQv2lXsjKq5B2FA

LTI pro の画面右上に「Pre-approve」というチェックボックスがあります。これをONにするとインストールボタンを押せるようになります。

「Manage」タブの「Configuration」セクションで「Configure」ボタンを押すと、現在設定しているアカウントに対してLTIで接続するための LTI Key を管理する画面が表示されます。

「+Create a new credential」ボタンを押してキーを生成すると、以下の3つの値が生成されます。

  • LTI URL
  • OAuth Redirect URL
  • LTI Key
  • LTI Secret

WebClass に LTI Key の登録

WebClass は LTI 1.1 に対応しています。LTI 連携オプションが有効になっていると、WebClass のシステム管理者のメニュー「システム管理」の中に「LTIツール設定」があります。

この画面を開きて、先ほど確認した Zooms.us のLTI キーを追加します。

  • ツール名:Zooms.us LTI pro
  • ツールURL :LTI URL
  • コンシューマ鍵:LTI Key
  • 秘密鍵:LTI Secret

コースで Zoom.us に接続する教材の追加

コース管理者でログインします。教材作成の画面を開くと、「LTIツール」という項目があります。

LTIツールを選び、教材作成画面で「利用可能ツール」からZoomを選択します。

この教材を保存して開くと、教材を開いた画面の中でZoomの会議一覧画面が表示されます。

「Schedule a New Meeting」ボタンで会議を追加します。また、会議を作成すると案内用のURLも取得できます。

このURLを控えておき、例えばコースのタイムラインに書き込んでおくと良いと思います。

学生がこの教材を開くと、ミーティングの作成はできませんが、用意してあるミーティングに参加することができます。

学生がZoomを開く

WebClass上に用意したZoom連携教材を学生が開くと、Web画面経由でZoomのアプリケーションが開きます。実際に参加するためには、学生がアプリをインストールしてアカウントを持っている必要があります。

この様子は、こちらの動画で確認できます。
https://www.youtube.com/watch?v=vFhAEoCF7jg&list=PLKpRxBfeD1kEM_I1lId3N_Xl77fKDzSXe&index=23

調査段階での不明事項

ここでは個人のBasicアカウントでLTI連携設定をしましたので、LTI連携教材を作成する時、LTIキーを生成したメールアドレスが設定された教員ユーザでなければ、Zoomsの会議一覧画面を開くことができません。簡易の検証のため、教員ユーザになる複数のZoomsアカウントでそれぞれLTIキーを生成し、個別にシステム管理者画面で設定しました。

ただし、学生はメールアドレスの設定がなかったとしても、Zoomsの会議の一覧を開いて、会議に参加しようとするところまで進めます。

組織アカウントや教育アカウントで設定したときの細かな違いはまだ検証できていません。

Ref

Getting Started with LTI Pro - Zoomappdocs
https://zoomappdocs.docs.stoplight.io/lti-pro-v2/welcome/getting-started

LTI Pro is now available in the Zoom Marketplace
https://support.zoom.us/hc/en-us/articles/201363333-Getting-Started-with-LTI

Zoom for education
https://zoom.us/education

LTI/LMS Systems - Zoom Help Center
https://support.zoom.us/hc/en-us/sections/200305523-LTI-LMS-Systems

Zoom - Youtube
https://www.youtube.com/channel/UC2SxmE4C-KAQuHaEfHVymgQ