先日、前々から実装してみたかったSSOにトライして、それがSPNEGO認証だったと理解し、環境ができたからじゃあDiscourseでSSOしてみるか…と思ったら、認証用のプログラムを書いて、それを動かすRuby on Rails(?)の専用の環境を作る必要があるっぽい。
興味はちょっとだけあるけど今じゃない感じなので、別の方向を探ってみたらSAML認証もあるらしい。
SAMLといえば…他にも使い道があるはず!と思って挑戦することを決意。
しかし、注意書きを見ながら長い旅になりそうだと思った。
Github / discourse / discourse-saml
結果的にできあがったのは、Discourseにアクセスするだけで自動的に(なければユーザーが作られて)ログインする仕組み。ドメインに参加しているPC限定だけど、かなり便利。
ドメインに参加していないPCからもIDとパスワードを入力すればログイン可能(ちょっとだけ難ありだけど)、Android端末からも同様にログイン可能、まぁまぁ問題なく運用はできそうだ。
やること。
- 環境
- 認証サーバーをインストール
- Keycloakの統合Windows認証設定
- Discourseの設定
- KeycloakとDiscourseのSAML設定
- おまけ Discourseのモデレーター同期
- やったこと
- 起きたこと
環境
https://temp.hogeserver.hogeddns.jp としてDiscourseを設定済み(ApacheでProxy)。ここに、
https://temp.hogeserver.hogeddns.jp:8443 としてKeycloakを構築していく。
ホスト名 | 用途 | 備考 |
---|---|---|
temp.hogeserver.hogeddns.jp | 今回の構築対象。 | keycloak 10.0.2(Docker版) discourse 2.6.0.beta1 Apache2 2.4.29-1ubuntu4.1 |
addc.hogeserver.hogeddns.jp | Samba ad dcを運用中。 Kerberos認証、LDAP(S)サービスを提供。 | Realmを管理 HOGESERVER.HOGEDDNS.JP |
認証サーバーをインストール
認証サーバーとしてKeycloakに挑戦してみようかと。後々色々活用できそうな予感満点。
Keycloakのインストール
いつもの通りがっつりインストール…とも考えたんだけれど、ソースからコンパイルする形になっていて目的達成に時間が掛かりそう。
KEYCLOAK / Downloads
Medium / Setup Keycloak Server on Ubuntu 18.04
DiscourseがDockerで動いているので、これもDockerで動かしてみようかと考えた。
KEYCLOAK / Keycloak on Docker
Dockerイメージのインストール
コマンド一発。初期ユーザーとしてuser:admin / password:admin を指定。
確かに楽だけど、どこに何があるのかサパーリ分からん。
$ sudo docker run -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:10.0.2 Unable to find image 'quay.io/keycloak/keycloak:10.0.2' locally 10.0.2: Pulling from keycloak/keycloak … 00:52:40,699 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990 00:52:40,700 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 10.0.2 (WildFly Core 11.1.1.Final) started in 34814ms - Started 689 of 994 services (708 services are lazy, passive or on-demand)
※この日のバージョンは10.0.2だった。マニュアルページは自動でバージョン表記が変わるんだろうか。
これで動作するんだけれど、コマンドが動いたまま…んー。
バックグラウンドで動作させるためには -d オプションが必要とのこと。
ThinkIT / Dockerコンテナの起動と廃棄
なので、しばらくこのままにしてブラウザでアクセスしてみる。
アクセステスト
ブラウザでアクセスしてみる。
http://temp.hogeserver.hogeddns.jp:8080
アクセスしたら、勝手にhttp→httpsにリダイレクトされてエラー。以下でどうにか解決。
かもメモ / Google Chrome 勝手にhttpsにリダイレクトされるにハマる
調べていると 「chrome://net-internals/#hsts」にアクセスして、Delete domain security policiesで該当ドメインを削除する
かもメモ
かっこいいなこれ。
Administration Consoleから入って、admin / adminでログインしてさらっと色々と回ってみた。洗練されたデザインでいい感じ。
ここで一旦コマンドプロンプトで [Ctrl]+[c] を押して止めてみた。
Dockerも止まった。
自動起動設定
Dockerイメージをインストールすると、それを再生するためのコンテナが作られているはずだ。
どんな名前で登録されているのか確認してみる。
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 41bf393541e4 quay.io/keycloak/keycloak:10.0.2 "/opt/jboss/tools/do…" 58 minutes ago Exited (0) 17 seconds ago hoge_hoge d19edf550884 local_discourse/app "/sbin/boot" 6 days ago Up 4 hours app
※この環境ではDiscourseが動いている。
名前が違っていて起動しにくいので、名前を変えてしまう。
$ sudo docker rename hoge_hoge keycloak
※この名前、インストールするたびにランダムに変わることが分かった。
自動起動するように設定。
$ sudo docker update --restart=always keycloak
これで再起動してみた。よし、自動で起動してくる、行けそうだ。
通信の保護(SSL)
Discourse用にオレオレなサーバー証明書を用意しているので、通信を保護しようと考えた。公式はJavaのkeystoreを作成する方法を説明している。
Keycloak Documentation / Version 10.0.2 / Server Installation and Configuration Guide
ApacheのProxy設定
Apacheで8443にProxyする。ファイルは新しいものを作ってもいいし、既存のものに追記してもいいと思う。今回は既存のものに追記。
/etc/apache2/sites-available/temp.hogeserver.hogeddns.jp.conf
Listen 8443 … <VirtualHost *:8443> ServerName temp.hogeserver.hogeddns.jp ServerAdmin webmaster@hogeserver.hogeddns.jp ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLProxyEngine on ProxyPreserveHost on RemoteIPHeader X-Forwarded-For RequestHeader set X-Forwarded-Proto "https" ProxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ SSLEngine on SSLCertificateFile /etc/ssl/private/temp.crt SSLCertificateKeyFile /etc/ssl/private/temp.key </VirtualHost>
Proxy設定はDiscourseで使ったものを流用。
証明書はオレオレ認証局で署名したもの。
設定を有効化する。
$ sudo systemctl reload apache2
この環境ではDiscourseをProxyする際に必要なモジュールを有効化済み。
reloadでエラーが出たら、必要モジュールをa2enmodで追加していく。
Dockerの環境変数を変更
KeyCloakがProxサーバーを通じたアクセスを許容するためには、Javaアプレット(?)の設定変更が必要。
設定は環境変数が反映されるようになっているので、環境変数をどこかで設定しなければ…
これのやり方がなかなか分からなかった~。
hawksnowlog / 一度 run したコンテナを削除せずに環境変数を設定する方法
環境変数は
/var/lib/docker/containers/<41bf393541e4・・・・・>/config.v2.json
にある。
赤文字部分は、docker ps -a で先頭が一致するディレクトリで物凄く長ーいものだった。
また、rootでないとアクセスできなかった。
ファイルの中身は1行で書かれている。以下を修正。
…BACKGROUND=1","PROXY_ADDRESS_FORWARDING=true","JBOSS_HOME=…
変更したら、Dockerサービスを再起動する。
# systemctl restart docker
アクセステスト
Proxy動作し始めたので、以下でアクセス。
https://temp.hogeserver.hogeddns.jp:8443
問題なくアクセスができ、先に進むことができそうだ。
Keycloakの統合Windows認証設定
Keycloakには最初にMasterというRealmがあって、これがKeycloak管理用。
各種サービスに接続するユーザー達は別のRealmを追加して管理していく。
統合Windows認証は、過去記事で実施できるようになっている。
(必要なものはそろっていて、サービスが正常に稼働している)
そこでまず、統合Windows認証で自動的にログインできる設定にしてみる。
Qiita / Keycloakで統合Windows認証を試してみる
Realmの追加
Keycloakにadminでログインし、Realmを追加する。
Masterと書かれているあたりをマウスでポイントすると、Add realmボタンが表示される。
※Realm wordpressを追加後に取ったキャプチャなのはご愛敬。
discourseという名前のRealmを追加する。
User Federationの追加
フェデレーションってのは、認証を連携する仕組みとのこと。
Kerberos連携の設定を追加する。
サイドメニューのUser Federationをクリックし、LDAPを選択して設定を入れていく。
途中でKerberos認証の設定も入れる感じ。
※必要な項目だけを以下で説明。
項目 | 設定値 | 備考 |
---|---|---|
プロバイダーID | 14nnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 作成時に生成され、変更できない。 |
有効 | オン | |
コンソール表示名 | ldap | わかりやすい名前で問題ない。 |
優先度 | 0 | |
ユーザーのインポート | オフ | Samba ad dc等の認証サーバーの負荷を軽減するにはオンが良いかも。 |
編集モード | READ_ONLY | |
登録の同期 | オフ | |
ベンダー | Active Directory | 作成時に指定。変更できない。 |
ユーザー名の LDAP 属性 | sAMAccountName | |
RDN LDAP 属性 | cn | |
UUID LDAP 属性 | objectGUID | |
ユーザーオブジェクトクラス | person, organizationalPerson, user | カスタムユーザーLDAPフィルターと合わせて利用者を限定できそう。 |
接続 URL | ldap://addc.hogeserver.hogeddns.jp | LDAPサーバーとしても動作するSamba AD DCサーバーを指定。LDAPSで接続するためには証明書を仕込んでおく必要があり、将来の課題とする。 接続テストもしておくと安心。 |
ユーザー DN | CN=Users,DC=hogeserver,DC=hogeddns,DC=jp | ユーザーが含まれる場所。Windows Serverの場合にはきっと違う値。 |
バインドタイプ | simple | LDAPサーバーの設定に合わせる。 |
StartTLS の有効 | オフ | LDAPサーバーの設定に合わせる。 |
Bind DN | administrator@hogeserver.hogeddns.jp | 問い合わせのためのアカウントを指定。administratorである必要はないはず、適切なアカウントで。 |
Bind のクレデンシャル | Bind DNに指定したユーザーのパスワード | 認証テストをしておくと安心。 |
カスタムユーザー LDAP フィルタ | ユーザーオブジェクトクラスと併せて利用者を限定できそう。 | |
検索スコープ | One Level | Samba ad dcではouをサポートしていないので、Userのところから情報を取り出す。ここは1階層なので、One Level。 |
パスワードポリシーの検証 | オフ | |
Eメールを信頼 | オフ | |
トラストストア SPI を使用 | Only for ldaps | |
接続プーリング | オン | ※機能の想像がつかない |
接続タイムアウト | 未指定 | |
読み取りタイムアウト | 未指定 | |
ページネーション | オン | ※機能の想像がつかない |
Kerberos 認証を許可 | オン | |
Kerberos Realm | HOGESERVER.HOGEDDNS.JP | Samba AD DCが管理するRealm。 |
Server Principal | HOST/temp.hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP | 一般にはHTTP/~というのが多いと思う。過去記事で利用したライブラリの関係でHOSTになっている。 |
KeyTab | /opt/jboss/keycloak/standalone/configuration/temp.keytab | 後でコンテナの中にファイルを持ち込む。 |
デバッグ | オフ | |
パスワード認証に Kerberos を使用 | オン | |
バッチサイズ | 1000 | ※機能の想像がつかない |
定期的なフル同期 | オフ | ユーザーをインポートしないので無意味。 |
定期的な変更ユーザーの同期 | オフ | ユーザーをインポートしないので無意味。 |
キャッシュポリシー | DEFAULT |
設定を保存する。
続いて、マッパーの確認。これらがユーザー情報としてLDAP+Kerberosから取り出されるんだと思う。
DiscourseのSAMLで要求されるのは、
username, email, firstName, lastName位かなと思われ、これらは自動生成されていると思われるが、念のためメモ。
項目 | 設定値 | 備考 |
---|---|---|
名前 | username | ログインアカウントになる。 |
マッパータイプ | user-attribute-ldap-mapper | |
User Model Attribute | username | |
LDAP Attribute | sAMAccountName | |
Read Only | オン | |
Is Mandatory In LDAP | オン | |
Is Binary Attribute | オフ |
項目 | 設定値 | 備考 |
---|---|---|
名前 | アカウントに関連付けられた連絡先になる。 | |
マッパータイプ | user-attribute-ldap-mapper | |
User Model Attribute | ||
LDAP Attribute | ||
Read Only | オン | |
Is Mandatory In LDAP | オフ | |
Is Binary Attribute | オフ |
項目 | 設定値 | 備考 |
---|---|---|
名前 | first name | |
マッパータイプ | user-attribute-ldap-mapper | |
User Model Attribute | firstName | |
LDAP Attribute | givenName | |
Read Only | オン | |
Is Mandatory In LDAP | オフ | |
Is Binary Attribute | オフ |
項目 | 設定値 | 備考 |
---|---|---|
名前 | last name | |
マッパータイプ | user-attribute-ldap-mapper | |
User Model Attribute | lastName | |
LDAP Attribute | sn | |
Read Only | オン | |
Is Mandatory In LDAP | オン | |
Is Binary Attribute | オフ |
keytabをコンテナの中に設置
Dockerのコンテナと特定のディレクトリやファイルを共有する方法はあると思うが、それに取り組む時間はないので後回し。
使用可能なkeytabをコンテナの中に放り込む。
keytabはここで作成したものを利用する。
このタイミングで使用したApcheのライブラリの都合(多分…)で、サービスプリンシパルの先頭がHTTPではなくHOSTになっている。名前は問題ではなく、利用までの理屈が整っていれば問題はないみたい。
場所は /opt/jboss/keycloak/standalone/configuration が良さそう。
(参照先サイトがここを使っていて、実際に中を見る限りここは適切だと思う)
# docker cp /etc/apache2/keytab/temp.keytab keycloak:/opt/jboss/keycloak/standalone/configuration
コピーしたkeytabのアクセス権を変更する。
# docker exec -u 0 -it keycloak /bin/bash --login [root@41bf393541e4 /]# chown jboss:root /opt/jboss/keycloak/standalone/configuration/temp.keytab [root@41bf393541e4 /]# chmod 660 /opt/jboss/keycloak/standalone/configuration/temp.keytab
アクセステスト
ドメインに参加したPCからアクセスし、SSOできることを確認する。
アクセス先となるURLはサイドメニューのクライアントをクリックし、クライアント ID が account の行にあるベース URL。
具体的には以下。
https://temp.hogeserver.hogeddns.jp:8443/auth/realms/discourse/account
SSOできなければログイン画面が、SSOできればログイン後のユーザー作成画面に遷移する。
これで、WindowsからkeycloakのRealm:KerberosにSSOできるようになった。
Discourseの設定
この設定で、Discourseは起動しなくなるが、後々設定を加えて動作させていく。
SAMLと自動ログインのプラグインを追加
この環境では、/opt/discourse にインストールしているので、標準の手順とは違った場所にファイルがある。
/opt/discourse/containers/app.yml
… hooks: after_code: - exec: cd: $home/plugins cmd: - git clone https://github.com/discourse/docker_manager.git - git clone https://github.com/discourse/discourse-saml.git - git clone https://github.com/clkao/discourse-sso-auto.git …
※赤文字部分を追加。プラグインのための環境変数と、プラグイン追加。
SAML認証には以下のプラグイン利用する(最初、ここに書かれている設定内容を見て途方に暮れた)。
一旦、設定は置いといて、プラグインを組み込む。再構築には時間が掛かるのだ。
Github / discourse / discourse-saml
また、SAML認証ができるようになっても自動ログインするわけではなく、with SAMLボタンを押す必要がある。
せっかく統合Windows認証の設定を済ませているのだから、勝手にログインしてもらいたい。
Github / clkao / discourse-sso-auto
プラグインを追加するので、再構築する。このコマンドは時間が掛かる。
$ sudo /opt/discourse/launcher rebuild app
自動ログイン的なプラグインはもう1つ見つかったけれど、管理メニューから設定を止められるようなので discourse-sso-auto を選択した。
見つけたもう1つのプラグインはこちら。
Github / procourse / discourse-saml-auto-login-plugin
KeycloakとDiscourseのSAML設定
DiscourseのSAMLはIdP開始のシナリオで動作するとのことで、Github?の設定をチラチラと見ながら設定を進めた。
IdP開始とはいっても、Keycloakに「クライアント」を追加して連携させるのね…(これが分からずかなり迷走した)。
Keycloakへのクライアント追加
Discourseとの通信について設定する。
なお、:8443(Keycloak自体)は設定値としては登場しない。
よく分からなくて色々と試行錯誤したが、基本的には「相手」と「通信内容」の定義をするから。
項目 | 設定値 | 備考 |
---|---|---|
クライアント ID | https://temp.hogeserver.hogeddns.jp | DiscourseのSAMLプラグインからClient IDとして送られてくる。 |
クライアントプロトコル | saml | |
クライアント SAML エンドポイント | https://temp.hogeserver.hogeddns.jp/auth/saml/callback | SAML を処理するマスター URLに反映される。 |
一旦これで作成し、その後に詳細項目を設定していく。現在動作している設定を記す。
もっとセキュリティを強化したり、もっと効率を高めたり、いらない設定を排除したり…とやれることはありそうな気がするが、とりあえず「署名が必要」を設定しているので、いくらかマシかなと思われる。
項目 | 設定値 | 備考 |
---|---|---|
クライアント ID | https://temp.hogeserver.hogeddns.jp | 最初に設定した値が反映されている。 |
名前 | Discourse | 使われている形跡が見当たらない。 |
説明 | 未設定 | |
有効 | オン | |
同意が必要 | オフ | |
ログインテーマ | 未設定 | |
クライアントプロトコル | samp | 最初に設定した値が反映されている。 |
AuthnStatement を含める | オン | |
OneTimeUse 条件を含める | オフ | |
ドキュメントを署名する | オン | |
REDIRECT 署名鍵検索の最適化 | オフ | |
アサーションを署名する | オン | |
署名アルゴリズム | RSA_SHA256 | |
SAML署名鍵名 | KEY_ID | |
正規化方式 | EXCLUSIVE | |
アサーションを暗号化する | オフ | |
クライアント署名が必須 | オン | |
POST Binding を強制 | オン | |
フロントチャンネルログアウト | オン | |
Name ID フォーマットを強制 | オン | |
Name ID フォーマット | ||
ルート URL | https://temp.hogeserver.hogeddns.jp | |
有効なリダイレクト URI | https://temp.hogeserver.hogeddns.jp/auth/saml/callback | |
ベース URL | 未指定 | |
SAML を処理するマスター URL | https://temp.hogeserver.hogeddns.jp/auth/saml/callback | |
IDP Initiated SSO の URL Name | login | IdP開始SSOのURLはこうなる。 https://temp.hogeserver.hogeddns.jp:8443/auth/realms/discourse/protocol/saml/clients/login これが[DISCOURSE_SAML_TARGET_URL]で設定するURL。 |
IDP Initiated SSO の RelayState | 未指定 | |
アサーションコンシューマサービスの POST Binding URL | https://temp.hogeserver.hogeddns.jp/auth/saml/callback | |
アサーションコンシューマサービスの Redirect Binding URL | https://temp.hogeserver.hogeddns.jp/auth/saml/callback | |
ログアウトサービスの POST Binding URL | 未指定 | |
ログアウトサービスの POST Binding URL | 未指定 | |
Assertion Lifespan | 未指定 | |
ブラウザーフロー | 未指定 |
クライアントにマッパーを追加
KeycloakがSSOの通信でDiscourseに伝えたいものは、マッパーで定義できた。
ユーザーフェデレーションのマッパーでLDAP+Kerberosから取り出した情報を、クライアントマッパーで渡してあげるイメージのようだ。
DiscourseのSAMLプラグインはemailとusername、firstName、lastNameを要求する。
name(表示名で、フルネームを想定しているらしい)は、firstName + " " + lastNameで生成される。
emailとusernameはデフォルトで渡されるので、firstNameとlastNameを追加する。
※名前を日本語で管理している場合の設定は後述。
firstNameを渡すマッパーの作成
項目 | 設定値 | 備考 |
---|---|---|
プロトコル | saml | 自動設定、変更不可。 |
ID | a90nnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動生成、変更不可。 |
名前 | first name | 最初に設定、変更不可。 わかりやすいものを設定。 |
マッパータイプ | User Property | 最初に選択、変更不可。 |
プロパティ | firstName | ユーザーフェデレーションの情報を取ってくる。 |
Friendly Name | 未設定 | |
SAML Attribute Name | firstName | この名前でDiscourseに伝わる模様。これで入れ替える |
SAML Attribute Name Format | Basic |
lastNameを渡すマッパーの作成
項目 | 設定値 | 備考 |
---|---|---|
プロトコル | saml | 自動設定、変更不可。 |
ID | 1aennnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動生成、変更不可。 |
名前 | last name | 最初に設定、変更不可。 わかりやすいものを設定。 |
マッパータイプ | User Property | 最初に選択、変更不可。 |
プロパティ | lastName | ユーザーフェデレーションの情報を取ってくる。 |
Friendly Name | 未設定 | |
SAML Attribute Name | lastName | この名前でDiscourseに伝わる模様。これで入れ替える |
SAML Attribute Name Format | Basic |
Discourse向けにSAML通信用の証明書を抜き出す
エンドポイントの情報から証明書を取り出す
レルムの設定にあるエンドポイント情報、「SAML 2.0アイデンティティー・プロバイダー・メタデータ」の情報を表示させる。
この中で<dsig:X509Certificate>で表示される長い文字列をコピーしてきて、作業ディレクトリに保管する。
~/keycloak.pem(名前は何でもOK)
-----BEGIN CERTIFICATE----- MIICoTCCAYkCBgFzeX7YeTANBgkqhkiG9w0BAQsFADAUMRIwEAYD… -----END CERTIFICATE-----
※赤文字部分を加えて証明書ファイルにする。
この証明書ファイルは、まるごとDiscourseの[DISCOURSE_SAML_CERT]の設定値になる。
証明書から指紋を取り出す
また、Discourseの[DISCOURSE_SAML_CERT_FINGERPRINT]として設定するため、証明書ファイルからFingerPrintを抽出する。
$ openssl x509 -in ~/keycloak.pem -noout -fingerprint SHA1 Fingerprint=13:01:33:C8:60:FB:02:AD…
Discourseの環境変数を設定
今までに取り出した情報+αでDiscourseのSAMLプラグインのための環境変数を設定を追加していく。
追加する場所は env セッションの中であればどこでも構わない。
/opt/discourse/containers/app.yml
… env: … ## Saml plugin setting ①DISCOURSE_SAML_TARGET_URL: https://temp.hogeserver.hogeddns.jp:8443/auth/realms/discourse/protocol/saml/clients/login ②DISCOURSE_SAML_CERT_FINGERPRINT: "13:01:33:C8:60:FB:02:AD:CF:57:69:50:89:BF:5B:27:1F:9A:1E:4E" ③DISCOURSE_SAML_CERT: "-----BEGIN CERTIFICATE----- MIICoTCCAYkCBgFzeX7YeTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlkaXNjb3Vyc2U<省略>72kM= -----END CERTIFICATE-----" ④DISCOURSE_SAML_SP_CERTIFICATE: "-----BEGIN CERTIFICATE----- MIICoTCCAYkCBgFzebYZEzANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlkaXNjb3Vyc2U<省略>JExk= -----END CERTIFICATE-----" ⑤DISCOURSE_SAML_SP_PRIVATE_KEY: "-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAuYBQkiitiZIxlJLI70WxLoHbr6pSLlQFVTqgrR9JyCR7vvZWZ0riB7M<省略>8RHQ== -----END RSA PRIVATE KEY-----" DISCOURSE_SAML_AUTHN_REQUESTS_SIGNED: true DISCOURSE_SAML_WANT_ASSERTIONS_SIGNED: true DISCOURSE_SAML_AUTO_CREATE_ACCOUNT: true …
※証明書のところは改行が含まれても大丈夫?と気になるところだけれども、問題なし。
④と⑤はKecloakのクライアントID https://temp.hogeserver.hogeddns.jp にあるSAML鍵から取得。
証明書は BEGIN CERTIFICATE ~ END CERTIFICATE、
秘密鍵は BEGIN RSA PRIVATE KEY ~ END RSA PRIVATE KEY
で囲んでいる。
その他に、
DISCOURSE_SAML_AUTHN_REQUESTS_SIGNED: true
DISCOURSE_SAML_WANT_ASSERTIONS_SIGNED: true
を設定。
これで、Keycloak側の情報が署名されていることを求める(つもり、実際Keycloak側で署名設定していないとエラーになる)。
最後に、
DISCOURSE_SAML_AUTO_CREATE_ACCOUNT: true
を設定。
これで、初めてアクセスしたユーザーのアカウントが即座に作られる。
既に再構築は済ませており、envを変更しただけなので、コンテナを作り直して環境変数の定義を反映させる。
再構築と比較してだいぶ時間短縮、無駄なイメージも作られない。
Discourse / How to change environment variable after docker has bootstrapped site?
$ sudo /opt/discourse/launcher destroy app $ sudo /opt/discourse/launcher start app
これで、Discorseが起動するようになり、統合Windows認証が動作するPCからアクセスすると、ユーザーが作られてログインした状態になっているはず。
アクセステスト
コンテナの再作成が終わったら、ドメインに参加したPCからDiscourseにアクセスしてみる。
SAML認証が上手く動作する状態になっていれば、DiscourseにアクセスしただけでKeycloakに遷移し、自動的に認証されてDiscourseに画面が遷移する。
上手くいかないようならログを見ながら設定を修正していく。
Discourseのログはこちら。
Keycloakのログはこちら。
Discourseの最終設定
Discourseは広くコミュニケーションするためのシステムだけど、組織で運用する場合には以下のような限定のための設定をしても良いと思う。
設定は管理者画面から。
項目 | 設定値 | 備考 |
---|---|---|
<ログイン> login required | チェック | ログインしていないユーザーには中身を見せない。 |
<ログイン> enable local logins | チェックを外す | Discourse標準のローカルログインを無効化。外部の認証しか受け付けなくなるので、SAML認証でミスるとサイトに入れなくなる。※ |
<ログイン> allow new registrations | チェックを外す | ドメインのユーザーだけが使えるようにしたいので、ユーザーを登録する機能を外した。 |
<プラグイン> sso auto enabled | チェック | discourse-sso-autoを有効化。これはプラグインをインストールした段階で有効になっている。 |
※ローカルログインを無効化した後にミスしてログインできなくなっても、回復させることは可能。
Keycloakの認証フロー条件見直し
デフォルト設定
Keycloakは認証フローを定義できる。デフォルトではKerberosがALTERNATIVEになっている。
この状態だと、ドメインに参加したPCでは自動的に認証が行われる。
ドメイン参加していないPCでは、Kerberos認証画面が表示されるが、何を入力しても認証は成功せず、Keycloakのログイン画面に遷移する。
ここで正しい情報を入力すれば、サービスにアクセスできる。
Windows 10 Homeでも同じ動作となった。
Android端末からアクセスしたところ、Keycloakのログイン画面が表示され、正しいIDとパスワードを入力すればサービスにアクセスができる。
Kerberos必須の設定
KerberosをREQUIREDにすると、ドメイン参加したPCからだけアクセスができる。
ドメイン参加していないPCでは、Kerberos認証画面が表示されるが、正しい情報を入力しても否認されてエラー画面に遷移する。
Android端末からアクセスすると、即座にエラー画面に遷移する。
おまけ Discourseのモデレーター同期
おまけ扱いするのはどうかと思うけれど、まずはSSOできることが最優先だった。
でも、ここまでできたので、モデレーターも自動で設定されるような形にしてみようと考えた。
ユーザーフェデレーションでロールを取り込む設定をして、ユーザーにロールを割り付ける。
そして、クライアントで特定のロールに含まれているユーザーにtrueフラグを立てた情報を送る。
Discourseの設定
SAMLプラグインに追加の設定をする。
/opt/discourse/containers/app.yml
…
env:
…
DISCOURSE_SAML_AUTO_CREATE_ACCOUNT: true
DISCOURSE_SAML_SYNC_MODERATOR: true
…
※赤文字部分を追加。
コンテナを再作成して環境変数を反映させる。
$ sudo /opt/discourse/launcher destroy app $ sudo /opt/discourse/launcher start app
Keycloakの設定
User Federationでrole-ldap-mapperを追加
ldap(Kerberos認証している)を開き、マッパーを追加する。
項目 | 設定値 | 備考 |
---|---|---|
ID | eb1nnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動設定、変更不可。 |
名前 | role map | 最初に設定、変更不可。 わかりやすいものを設定。 |
マッパータイプ | role-ldap-mapper | 最初に設定、変更不可。 |
LDAP Roles DN | CN=Users,DC=hogeserver,DC=hogeddns,DC=jp | Samba ad dcはOU対応していないため、グループを使う。OUを使っても良いのだろうと思う。 |
Role Name LDAP Attribute | cn | |
Role Object Classes | group | |
Membership LDAP Attribute | member | |
Membership Attribute Type | DN | |
Membership User LDAP Attribute | sAMAccountName | |
LDAP Filter | (objectClass=group) | ユーザーも同じところにあるので、フィルターを掛ける。 |
Mode | READ_ONLY | |
User Roles Retrieve Strategy | LOAD_ROLES_BY_MEMBER_ATTRIBUTE | もしかしたら、RECURSIVELYの設定が必要かもしれない。 ※RECURSIVELYを指定すると、取ってきたgroupが持っている子供もたぐっていくようになる。groupをまとめたような親グループを指定する場合には設定しておく。2021/05/05追記 |
Member-Of LDAP Attribute | memberOf | |
Use Realm Roles Mapping | オン | |
Client ID | account |
クライアントにJavascript Mapperを追加
DiscourseのSAMLプラグインはisModeratorでtrue(または1)が戻されたユーザーをモデレーターにする。
特定のグループに含まれたユーザー(=上の設定で同じ名前のロールに含まれる)ならばtrueを戻すJavascript Mapperを作る。
項目 | 設定値 | 備考 |
---|---|---|
プロトコル | saml | 自動設定、変更不可。 |
ID | 966nnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動設定、変更不可。 |
名前 | isModerator | 最初に設定、変更不可。 Discourseが求める名前。 |
マッパータイプ | Javascript Mapper | 最初に選択、変更不可。 |
定義するスクリプトはこんな内容にした。
/** * Available variables: * user - the current user * realm - the current realm * clientSession - the current clientSession * userSession - the current userSession * keycloakSession - the current keycloakSession */ //insert your code here... exports=false; for each ( var role in user.getRoleMappings()) { if ( role.getName() == 'GroupName' ) { exports=true; break; } }
※GroupNameのところにモデレーターにしたいグループの名前を入れる。
もっと格好いい書き方(効率の良い書き方、メンテナンス性が高い書き方)があるかもしれないが、Javascriptのコーディング経験はないのでご容赦。
呼び出せる関数については、ここを参考しにした。他の情報は見つからなかった。
Github gist / Steps to provide Hasura Claims in Keycloak generated JWT
やったこと
Discourseのログ
ログについてはここに書かれていた。
Discourse / Where does Discourse store and show logs?
Web UI
運用上の多くは管理者メニューから見ることができた。
また、GUIログビュアーがあり、管理者メニュー → ログ → エラーログ で見ることができた。
https://temp.hogeserver.hogeddns.jp/logs/
コンテナに入って見られるログ
コンテナのディレクトリの一部が共有になっているようで、以下にログが見えている。
/var/discourse/shared/standalone/log/rails
/var/discourse/shared/standalone/log/var-log
コンテナには以下のコマンドで入ることができる。
$ sudo /opt/discourse/launcher enter app
ここにログがある。
/shared/log/rails
/var/log
Keycloakのログ
ログを見る
ものを知らないのは恐ろしい…設定が大体終わった今になってログの見方が分かった。
■Keycloak $ sudo docker logs -f --tail 10 keycloak
ログレベルを変える
認証が上手くいかないので、ログを見てみることにした。
dockerhub / jboss / keycloak ※Specify log levelのところ
今見ているログについては、2行目のを実行したところでデバッグログが出力されるようになった。
$ sudo docker exec -u 0 -it keycloak /bin/bash --login [root@41bf393541e4 /]# /opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=logging/console-handler=CONSOLE:change-log-level(level=DEBUG)' [root@41bf393541e4 /]# /opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=logging/root-logger=ROOT:change-root-log-level(level=DEBUG)'
元に戻すには、DEBUGのところをINFOに変える。
Discourseのローカルログインを強制的に復活させる
ログイン関連の設定をしていると、ミスってログインできなくなり、ローカルログインしたいけどできない…。
こんなときは、中に入ってコマンドを叩けば復旧できる。
Discourse / Official Single-Sign-On for Discourse (sso)
$ sudo /opt/discourse/launcher enter app root@temp-app:/var/www/discourse# rails c [1] pry(main)> SiteSetting.enable_local_logins = true => true [2] pry(main)> exit root@temp-app:/var/www/discourse# logout
DiscourseのSAML認証で作られるアカウントのフルネームの調整
サイトにアクセスすると自動的にSAML認証が起動し、初めてのログインならアカウントが作られるようになったのだが、名前(フルネーム)が中途半端。
当初、SAML認証のプラグインはユーザーのフルネームを書き換える機能を提供していないようだった。
Discourse / Discourse-saml as sole login method
しかし、少なくとも最終ソースでは提供がされている。
Github / discourse / discourse-saml
実際、本編で記載したとおり、クライアントのマッパーでSAML認証プラグインに情報を渡せば、フルネームは作られる。
しかし…
- ドメインコントローラーで日本語の姓名を管理している場合、残念表記になる。
e.g.) Taro Yamada → 太郎 山田 - fullNameを生成して渡しても、firstName + " " + lastNameで上書きされる。
firstNameとlastNameを渡さないようにしても、何か別の情報で上書きされる。
という課題が残った。対策は3つ。
- KeycloakからfirstNameとlastNameの値を入れ替えて渡す
- プラグインのソースでfirstNameとlastNameを入れ替える
- KeycloakでfullNameを作って渡し、DiscourseではfullNameしか使わない
KeycloakからfirstNameとlastNameの値を入れ替えて渡す
運用上はメンテナンスでミスが発生しにくいやり方かなと思われる。
ただし、SAML認証の情報が他でも使われるようになると(何かでfirstNameが使われるとか…)、負の影響が出てくるので注意。
クライアント → https://temp.hogeserver.hogeddns.jp を開き、マッパータブを開く。
ユーザーフェデレーション(LDAP)で取り出した情報を、クライアントでDiscourseに渡すイメージ。
firstNameとしてlastNameを渡すマッパーの作成
項目 | 設定値 | 備考 |
---|---|---|
プロトコル | saml | 自動設定、変更不可。 |
ID | a90nnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動生成、変更不可。 |
名前 | first name reverse | 最初に設定、変更不可。 わかりやすいものを設定。 |
マッパータイプ | User Property | 最初に選択、変更不可。 |
プロパティ | firstName | この情報を取ってくる。 |
Friendly Name | 未設定 | |
SAML Attribute Name | lastName | この名前でDiscourseに伝わる模様。これで入れ替える |
SAML Attribute Name Format | Basic |
lastNameとしてfirstNameを渡すマッパーの作成
項目 | 設定値 | 備考 |
---|---|---|
プロトコル | saml | 自動設定、変更不可。 |
ID | 1aennnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動生成、変更不可。 |
名前 | last name reverse | 最初に設定、変更不可。 わかりやすいものを設定。 |
マッパータイプ | User Property | 最初に選択、変更不可。 |
プロパティ | lastName | この情報を取ってくる。 |
Friendly Name | 未設定 | |
SAML Attribute Name | firstName | この名前でDiscourseに伝わる模様。これで入れ替える |
SAML Attribute Name Format | Basic |
プラグインのソースでfirstNameとlastNameを入れ替える
Discourseのプラグインに手を入れて姓名の順になるように変更。
プラグインのソースが変わったときに検知して、都度修正することができれば安全。
fullNameを生成する処理を修正
firstName + lastNameとしている処理を変更する。
$ sudo /opt/discourse/launcher enter app root@temp-app:/var/www/discourse# vi plugins/discourse-saml/lib/saml_authenticator.rb
という具合で編集を開始。
/var/www/discourse/plugins/discourse-saml/lib/saml_authenticator.rb
… result.name = begin if attributes.present? fullname = attributes['fullName'].try(:first) // fullname = "#{attributes['firstName'].try(:first)} #{attributes['lastName'].try(:first)}" fullname = "#{attributes['lastName'].try(:first)} #{attributes['firstName'].try(:first)}" end fullname ||= result.name fullname end …
※firstNameとlastNameを入れ替え。
編集が終わったらDiscourseを再起動する。
$ sudo /opt/discourse/launcher restart app
KeycloakでfullNameを作って渡し、DiscourseではfullNameしか使わない
こちらもDiscourseプラグインに手を入れるので、ソースが変わったときに検知して修正する必要がある。
fullNameの生成にはJavascript Mapperを利用することになったので、学習の意味でやってみた。
fullNameを生成する処理を修正
firstName + lastNameとしている処理を無効化し、fullNameを受け取るようにする。
$ sudo /opt/discourse/launcher enter app root@temp-app:/var/www/discourse# vi plugins/discourse-saml/lib/saml_authenticator.rb
という具合で編集を開始。
/var/www/discourse/plugins/discourse-saml/lib/saml_authenticator.rb
…
result.name = begin
if attributes.present?
fullname = attributes['fullName'].try(:first)
// fullname = "#{attributes['firstName'].try(:first)} #{attributes['lastName'].try(:first)}"
end
fullname ||= result.name
fullname
end
…
※firstNameとlastNameからfullNameを作る処理を無効化。
編集が終わったらDiscourseを再起動する。
$ sudo /opt/discourse/launcher restart app
fullNameを生成するマッパーの作成
LDAPで取得した値を組み合わせてfullNameを作成する Javascript Mapper を作成する。
項目 | 設定値 | 備考 |
---|---|---|
プロトコル | saml | 自動設定、変更不可。 |
ID | 1f0nnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn | 自動生成、変更不可。 |
名前 | fullName | 最初に設定、変更不可。 Discourseが求める名前。 |
マッパータイプ | Javascript Mapper | 最初に選択、変更不可。 |
定義するスクリプトはこんな内容にした。
/**
* Available variables:
* user - the current user
* realm - the current realm
* clientSession - the current clientSession
* userSession - the current userSession
* keycloakSession - the current keycloakSession
*/
//insert your code here...
var fName = user.getFirstName();
var lName = user.getLastName();
exports = lName + " " + fName;
//var flName = user.getFirstAttribute("displayName");
//exports = flName;
firstNameやlastNameは取り出す関数が用意されている。
ユーザーページで表示される基本的な情報はこれで取り出すのだろう。
一方、ユーザーフェデレーションのマッパーで例えばdisplayNameを作った場合、displayNameで取得したLDAPの情報はgetFirstAttributeで取り出す。
Kerberosで取った情報と、LDAPで取った情報とで扱いが違うのかもしれない。今回の調査はここまで。
関数を利用するにあたって、この投稿で示されているソースがわかりやすかった。
stackoverflow / How to create a Script Mapper in Keycloak?
user: Source JavaDoc(リンク切れ https://www.keycloak.org/docs-api/6.0/javadocs/org/keycloak/models/UserModel.html)
André B.さんの回答
realm: Source JavaDoc(リンク切れ https://www.keycloak.org/docs-api/6.0/javadocs/org/keycloak/models/RealmModel.html)
token: Source JavaDoc(リンク切れ https://www.keycloak.org/docs-api/6.0/javadocs/org/keycloak/representations/IDToken.html)
userSession: Source JavaDoc(リンク切れ https://www.keycloak.org/docs-api/6.0/javadocs/org/keycloak/models/UserSessionModel.html)
keycloakSession: Source JavaDoc(リンク切れ https://www.keycloak.org/docs-api/6.0/javadocs/org/keycloak/models/KeycloakSession.html)
SAMLRequestの中身を確認する
Discourseから認証要求は飛んでいるけれど、userId=nullとなって前に進まない。どんなリクエストが飛んでいるのか見てみたいと思った。
URL形式をデコードし、Base64形式なのをデコードし、inflateすれば見られるらしい。
Github / onelogin / ruby-saml / Generated SamlRequest doesn't Base64 decode properly #394
これをワンラインで実現できなかったので、シェルを作成。
samldecode
#!/bin/bash MGCODE="\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" # URL形式からのデコード TGCODE=`urlencode -d "$1"` # Base64形式からのデコード TGCODE=`echo $TGCODE | base64 -d` # gzip用にマジックコードを追加してinflate TGCODE=`printf "$MGCODE%s" "$TGCODE" | gzip -dc 2>/dev/null` # 整形して表示 echo "----- Result -----" echo $TGCODE | xmllint --format -
※inflateは実際にはzlibでdecompressしているらしく、gzipコマンドに入れてみたけれども展開できず。マジックコードを付ければ良いと教えてくれたのでやってみたら上手くいった。
it-swarm-ja.tech / UNIXでzlibデータを解凍する方法は?(リンク切れ)
シェルから呼び出すコマンドをインストールし、実行権を付ける。
$ sudo apt install gridsite-clients ← urlencodeコマンドを使うため $ sudo apt install libxml2-utils ← xmllintコマンドを使うため $ chmod +x samldecode
ブラウザでアクセスしてエラーとなった時に、URLに表示されている
?SAMLRequest=~~~
の~~~部分をコピーしてこのスクリプトに渡したら、デコードしてくれた。
$ ./samldecode ~~~
----- Result -----
<?xml version="1.0"?>
<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://temp.hogeserver.hogeddns.jp/auth/saml/callback" Destination="https://temp.hogeserver.hogeddns.jp:8443/auth/realms/Kerberos/protocol/saml" ID="_3702917b-61f4-45a3-a9cd-afd803913810" IssueInstant="2020-07-11T22:57:36Z" Version="2.0">
<saml:Issuer>https://temp.hogeserver.hogeddns.jp</saml:Issuer>
</samlp:AuthnRequest>
こうしてみると、確かに認証は要求しているけれど、中身がよく分からない。
Cybozu Inside Out / SAML認証ができるまで
Qiita / (ちょっと噛み砕いた)SAML入門
項目 | 意味 | 設定値 |
---|---|---|
xmlns:saml | urn:oasis:names:tc:SAML:2.0:assertion | |
xmlns:samlp | urn:oasis:names:tc:SAML:2.0:protocol | |
AssertionConsumerServiceURL | Discourseが認証応答を受け取るURL | https://temp.hogeserver.hogeddns.jp/auth/saml/callback |
Destination | リクエストの宛先 | https://temp.hogeserver.hogeddns.jp:8443/auth/realms/Kerberos/protocol/saml |
ID | ユニークなランダム文字列 | _3702917b-61f4-45a3-a9cd-afd803913810 |
IssueInstan | 認証要求をした日時 | 2020-07-11T22:57:36Z |
Version | SAMLバージョン | 2.0 |
<saml:Issuer> | SPのID | https://temp.hogeserver.hogeddns.jp |
後から考えると、IdP開始のシナリオでsaml:Issuerがhttps://temp.hogeserver.hogeddns.jpとなっているんだから、これがKeycloakでいうところのClientIDなのかもしれない…と気付いた。
結果的にはそれで上手くいったように思われる。
起きたこと
KeycloakをProxyしたらMixed Contentエラー
こんなエラーが出た。楽をしようとして、結果的に時間が掛かるパターン。
Mixed Content: The page at 'https://temp.hogeserver.hogeddns.jp:8443/auth/admin/master/console/' was loaded over HTTPS, but requested an insecure script 'http://temp.hogeserver.hogeddns.jp:8443/auth/js/keycloak.js?version=up50l'. This request has been blocked; the content must be served over HTTPS.
コンテナの中に入ってみる。
■1人目のユーザーでログイン
$ sudo docker exec -it keycloak /bin/bash --login
[jboss@b8d8e12d9516 /]$ cd
[jboss@b8d8e12d9516 /]$ pwd
/opt/jboss
■ルートユーザーでログイン
$ sudo docker exec -u 0 -it keycloak /bin/bash --login
[root@b8d8e12d9516 /]#
このイメージにはfindやvi等が入っていなくて、この中でファイルを編集することはできない。
仕方がないので、中からファイルを取りだして、書き換えて送り込むことを考える。
今回はstandaloneで動いてる?となると、恐らくこのファイルが編集対象。
/opt/jboss/keycloak/standalone/configuration/standalone.xml
結果は外れ。これが対象だった(少なくともログイン画面では)。
/opt/jboss/keycloak/standalone/configuration/standalone-ha.xml
$ sudo docker cp keycloak:/opt/jboss/keycloak/standalone/configuration/standalone-ha.xml ./
ファイルを編集。
… <server name="default-server"> <ajp-listener name="ajp" socket-binding="ajp"/> <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING:false}" enable-http2="true"/> ↓ <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true" enable-http2="true"/> …
編集結果を書き戻し、コンテナを再起動する。
$ sudo docker cp standalone-ha.xml keycloak:/opt/jboss/keycloak/standalone/configuration/standalone.xml $ sudo docker restart keycloak
確かにこれで動く(半日かかったぜ…)。
でも、環境変数で動いてくれるっぽいから、そっちをちゃんと調べよう。となって、本編の解決策となった。
Keycloakが再起動を繰り返す
Proxyを受け入れるための環境変数を変えようとして、runコマンドに環境変数を追加して起動してみたところ、Keycloakが再起動を繰り返すようになった。
コンテナが2つあるけれど、イメージは1つという状態を作り出した結果、競合的な問題が発生したのだろう。
設定をしっかりした状態だったら設定内容の保全をしながら起動できる方法を考えたと思うが、まだ設定などほとんどしていない状態だったので、コンテナもイメージも全てをきれいに削除して、runコマンドを叩いた。
Keycloakが自動起動しない
自動起動するはずのKeycloakとDiscourseが起動しなくなっている。何でかなぁと思ってsshでログインし、docker.serviceが起動していないことが判明。
$ sudo systemctl enable docker
これで、しっかりと自動起動するようになった。
Discourseのイメージがたくさんある
使用しているディスク容量がやけに増えているなぁ…と思ったらこんなことに。
# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE local_discourse/app latest 5fa587e920ea 2 hours ago 2.65GB <none> <none> 432b2305cbc8 5 hours ago 2.65GB <none> <none> d35bbbea2ae8 5 hours ago 2.65GB <none> <none> f38f6b5c6fc0 6 hours ago 2.65GB <none> <none> 6fbda624f25e 6 hours ago 2.65GB <none> <none> 26f3332683f5 6 hours ago 2.65GB <none> <none> de00ef9de579 8 hours ago 2.65GB <none> <none> febf54a5c910 13 days ago 2.61GB <none> <none> 95eca1c4afae 13 days ago 2.61GB quay.io/keycloak/keycloak 10.0.2 dc8d0176a668 5 weeks ago 740MB discourse/base 2.0.20200512-1735 991acdba0b1f 8 weeks ago 2.22GB
再構築するたびにイメージが新たに作られるんだなこれ。
ここで示唆されているオプションを指定してlauncherを実行してみた。
Github / A rebuild doesn't remove the old docker image #21
# cd /opt/discourse # ./launcher cleanup WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N] y Total reclaimed space: 0B WARNING! This will remove all images without at least one container associated to them. Are you sure you want to continue? [y/N] y Deleted Images: deleted: sha256:febf54a5c910db3b03b628bba4cc8693bcdea4bbd7cb46ce297178db357eb648 deleted: sha256:1c08a84f8c2a8240bb773779e5bac00d19192d39f14c03d5df7a9ab2ed35a172 deleted: sha256:95eca1c4afae367fffd6ec0fe65ea5da77ae6ebf242b6335fd8961b5b723209d deleted: sha256:0b209505686fd47327d14e029534fb5921a2c2d90294ef0cd686dd5091bcfc67 deleted: sha256:de00ef9de5799ae2eaacf054b1f935c7969337eea11ce6ae0705b446a7ab8240 deleted: sha256:98b60bf88bef6a6bbe3c8049319a483d67defbb51491a22911844c5cae4d2e0d deleted: sha256:26f3332683f51cfaf39d4745076fe367e43b4b10981afb2187ca594649751cfd deleted: sha256:d021db6b2caebfe342497bd9c6beefad2dfc7035ff7e9eaac315e7aa631bb779 deleted: sha256:f38f6b5c6fc054236e4288217dc96f95c3d4cc5711b6353475728dfcd26a3563 deleted: sha256:e2ba479751e8a949545fc5955370c8eca28f5a48f9e606eb86c90991a0f45635 deleted: sha256:432b2305cbc85ec4bc67761775203167db366224c684f913295c685af4d21b25 deleted: sha256:2625555c5af1a5f3f76a6c99e41d3e11e284e04b400925da3c925cd2ebe9c672 deleted: sha256:6fbda624f25edf8c56ebd00887cb75528ee8b588004df850b1d10f16835a858f deleted: sha256:67f6f72f94b1d2cf0f1a1a6a533bcaa259f58a81679da31cf847ec9b986395f9 deleted: sha256:d35bbbea2ae81b17e335269a9d1bfae3afc8f79f6b8284957fb4dc9e4293c55b deleted: sha256:7e0c8a2085d794d49b7b5dd8fee55eb16fc1eeddcf567f461190808fb98ea4cf untagged: discourse/base:2.0.20200512-1735 untagged: discourse/base@sha256:7f6c5be23a8e4237cecafaca9d041de5964f8237345b7b183cebdee1f73ed024 Total reclaimed space: 3.386GB
古くなったイメージが消されて、容量が戻ってきた。
KeycloakとWordpressのSAML認証連携を試す
DiscourseのSAML認証がどうしても構成できず、これは一度上手くいく連携というものを体験すべき、と考えた。
前々から読んでいたつもりだったんだけど、いざ設定をするとなって、色々と気付かせてくれたのがこちらの記事。
Qiita / KeycloakでSAMLを使ってみる(WordPress編)
これってどういう意味かな?これって?これって?と注意深く見ることが大切なんだけど、読むだけではなかなか頭に入らない性格なんだなと痛感。
最終的には、ちゃんと自動ログインできるようになった。
MariaDBが上手くインストールできない
WordPressをインストールする過程で間違えてMySQLをインストールしてしまった。
MySQLをpurgeした後、mariadbをインストールしようとしたら、異常に時間が掛かるし、上手くいかない。
これはこれで小さくないテーマなので記事にしてみた。
WordPressのOneLogin SAML SSOでエラー
上手く動く事例を作成するために、OneLogin SAML SSOを動作させたところ、エラーが発生。
[19-Jul-2020 10:16:39 UTC] PHP Fatal error: Uncaught Error: Class 'DOMDocument' not found in /var/www/wordpress/wp-content/plugins/onelogin-saml-sso/php/lib/Saml2/Response.php:100
必要なライブラリがあるらしい。
ajike switch / 【解決方法】 Fatal error: Class ‘DOMDocument’ not found
$ sudo apt install php7.2-xml $ sudo systemctl restart apache2
これで先に進んだ。
WordPressでデバッグログを出力したい
WordPressのエラーログをファイルにだけに出力したい。
Qiita / WordPressのデバッグモード(ログ出力)
/var/www/wordpress/wp-config.php
… //define( 'WP_DEBUG', false ); define( 'WP_DEBUG', true ); if ( WP_DEBUG ) { define( 'WP_DEBUG_LOG', true ); define( 'WP_DEBUG_DISPLAY', false ); @ini_set( 'display_errors',0 ); } …
※この設定、いいなぁ。WP_DEBUGをfalseにすれば、元の状態に戻るもん。
ログファイルは、/var/www/wordpress/wp-content/debug.log に出力される。
さいごに
SSOはあくまで認証を1つのサーバーで行おうとする仕組みであって、自動ログインとは違う。
自動ログインってのはブラウザ側も協調して行われる仕組みで、[with SAML]ボタンをクリックしたときに起きることを自動的に呼び出してくれると分かった。
ちょっとややこしいけれど、理解できて良かった部分。
ドメインに参加していないPCでChromeを使ってアクセスすると、絶対に成功しない認証の要求がある(その後にKeycloakが表示するログイン画面ではログインができる)。
これをどうにかして止めたいんだけど、どうにもその方法が見つけられなかった。何かそういうヘッダーでも送ればいいのか?残課題。
今まで避けてきたSSOだけど、どうにか第一歩を踏み出せたような気がする。
コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他