Apache HTTP Server + mod_auth_openidc で OpenID Connect (OIDC) 認証が必要な Web サイトを作ってみます。
本記事は「1. 準備編」「2. d アカウント・コネクト編」に続く「3. Google アカウント編」です。d アカウント・コネクト編の設定が終わっている状態から、d アカウント・コネクトではなく Google アカウントでソーシャルログインできるように変更してみます。次の記事は「4. マルチプロバイダ編」として d アカウント・コネクトと Google アカウントの両方でソーシャルログインできるようにします。
もしかしたらマズい設定などがあるかもしれません。気が付いた方はご指摘いただけるとありがたいです。
Google アカウント
OpenID Connect (OIDC) に対応していてソーシャルログインに使えるものとして有名ですね。支払設定をしなくてもとりあえず使うことができました。$300 相当の無料トライアルを有効化しなければクレジットカード情報の登録も必要ありませんでした(2022 年 6 月現在)。
設定
今回は公開ステータス「テスト」のままで使ってみます。そのため後で登録するテストユーザしか使えません。「アプリを公開」にすると本番環境となり全ユーザが使えるようになりますが、審査が必要などいろいろあるようです。支払設定なども必要になるのかもしれませんが、やっていないのでわかりません。設定方法などは本記事では説明しませんのでご自分でお調べください。
プロジェクト作成
ブラウザで https://console.cloud.google.com/apis/ を開き「API とサービス」画面で適当にプロジェクトを作成します。プロジェクト名、プロジェクト ID、場所など全部デフォルトのまま作成してみました。プロジェクト名は後から変更可能、プロジェクト ID は後から変更できないようです。
「OAuth 同意画面」の設定項目
「API とサービス」画面で作成したプロジェクトが選択されている状態で「OAuth 同意画面」をクリックしてアプリを登録します。ほとんどの項目は後から変更可能みたいなので適当に設定すればよさそうです。
- ユーザの種類
- 「外部」に設定します
- 「内部」は Google Workspace 用のものでメンバ限定などができるようです
- 「外部」に設定します
- スコープ
- 以下の 3 種類を設定します
(それ以外の選択肢は選択できないし、
新しいものを追加することもできないようです)- .../auth/userinfo.email: Google アカウントのメインのメールアドレスの参照
- .../auth/userinfo.profile: ユーザーの個人情報の表示(ユーザーが一般公開しているすべての個人情報を含む)
- openid: Google で公開されているお客様の個人情報とお客様を関連付ける
- 以下の 3 種類を設定します
- テストユーザ
- とりあえず自分だけ追加しておきます
- 100 アカウントまで追加可能のようです
- とりあえず自分だけ追加しておきます
「認証情報」の設定項目
次に「API とサービス」画面で「認証情報」をクリックします。「+認証情報を作成」をクリックして「OAuth クライアント ID」を選びます。
- アプリケーションの種類
- 選択肢はいろいろあるようですが mod_auth_openidc で使うなら「ウェブアプリケーション」にします
- 名前
- 適当にデフォルトのままにしてみました
- 承認済みの JavaScript 生成元
- 何も入れません
- 承認済のリダイレクト URI(d アカウント・コネクト編と同じ設定にします)
https://example.com/oidc/redirect_uri
「作成」するとクライアント ID とクライアントシークレットが表示され、それらが入った json をダウンロードできるようになりますので、ダウンロードしておきます。
mod_auth_openidc
d アカウント・コネクト編で作った /etc/apache2/mods-available/auth_openidc_d_account_connect.conf
と同様の設定ファイルを /etc/apache2/mods-available/auth_openidc_google_account.conf
に作ります。同様にクライアント ID およびクライアントシークレットも /etc/apache2/mods-available/auth_openidc_client_secret_google.conf
に置いておきます。
設定
/etc/apache2/mods-available/auth_openidc_google_account.conf
の設定です。
OIDCProviderMetadataURL
Google Account は OpenID Connect Discovery に対応しているので、その URL を設定します。これで多くの設定項目が自動的に取得できるため、いちいち設定ファイルに書かなくて済むようになります。
OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
OIDCScope
スコープを設定します。「OAuth 同意画面」で 3 つ設定したので、それに対応する 3 種類を書いておきます。
OIDCScope "openid email profile"
OIDCResponseType
フローを設定します。「認証情報」で「ウェブアプリケーション」と設定したので、それに対応する設定にします。
OIDCResponseType "code"
設定ファイル
以上により設定ファイル /etc/apache2/mods-available/auth_openidc_google_account.conf
の全体は以下のようになります。
OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
OIDCScope "openid email profile"
OIDCResponseType "code"
クライアント ID およびクライアントシークレット
クライアント ID およびクライアントシークレットは別ファイル /etc/apache2/mods-available/auth_openidc_client_secret_google.conf
に書いておきます。
OIDCClientID xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
OIDCClientSecret XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
念のため、オーナーとパーミッションをいじって他のユーザから見えないようにします。
$ cd /etc/apache2/mods-available/
$ sudo chown www-data:www-data auth_openidc_client_secret_google.conf
$ sudo chmod 600 auth_openidc_client_secret_google.conf
Apache サイト設定
/etc/apache2/sites-available/example.com-ssl.conf
でインクルードしている mod_auth_openidc の設定ファイルを先ほど作成した設定ファイルへ変更します。
Include mods-available/auth_openidc_d_account_connect.conf
Include mods-available/auth_openidc_client_secret.conf
を
Include mods-available/auth_openidc_google_account.conf
Include mods-available/auth_openidc_client_secret_google.conf
に変更します。ファイル全体としては以下のようになります。
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-test-example-com.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-test-example-com.key
SSLCertificateChainFile /etc/apache2/ssl.crt/test-intermediate-ca.pem
Include mods-available/auth_openidc_google_account.conf
Include mods-available/auth_openidc_client_secret_google.conf
OIDCRedirectURI https://example.com/oidc/redirect_uri
OIDCCryptoPassphrase foobarbaz
OIDCCookiePath /oidc/
OIDCDefaultLoggedOutURL https://example.com/loggedout.html
<Location /oidc/>
AuthType openid-connect
Require valid-user
Options +Includes
DirectoryIndex index.shtml index.html
</Location>
</VirtualHost>
</IfModule>
設定の確認とサービス再起動
設定が正しいか確認します。
$ sudo apache2ctl configtest
Syntax OK
として上記のように Syntax OK と出たら確認 OK ですので、
$ sudo service apache2 restart
として再起動します。
動作確認
Windows のブラウザ(Edge など)で https://example.com を開き、「ログイン」をクリックします。Google アカウントの認証画面になり、認証されたら OIDC 動作確認用コンテンツ「OpenID Connect ログインしました」画面(ログイン中画面)になります。ここでは mod_auth_openidc が環境変数 REMOTE_USER に設定した認証したユーザの識別子が表示されます。
この識別子はアカウントを一意に識別することができる文字列ではあるようですが、Google アカウントの ID やメールアドレスとは全く関係ない文字列になっています。
スコープ
d アカウント・コネクト編と異なり、スコープに openid だけではなく email と profile も設定しましたので、こちらの情報も得られているハズです。そこで、OIDC 動作確認用コンテンツを少し書き換えてこれらの情報も表示できるようにしてみます。
コンテンツ
/var/www/example.com/oidc/index.shtml
の OIDC 動作確認用コンテンツを以下のように書き換えます。
<DOCTYPE! html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>OpenID Connect ログインしました</title>
</head>
<body>
<h1>OpenID Connect ログインしました</h1>
<p>REMOTE_USER=<!--#echo var="REMOTE_USER" --></p>
<p>
OIDC_CLAIM_email=<!--#echo var="OIDC_CLAIM_email" --><br/>
OIDC_CLAIM_email_verified=<!--#echo var="OIDC_CLAIM_email_verified" -->
<br/>
</p>
<p>
<img src="<!--#echo var="OIDC_CLAIM_picture" -->"
alt="OIDC_CLAIM_picture" /><br/>
OIDC_CLAIM_name=<!--#echo var="OIDC_CLAIM_name" --><br/>
OIDC_CLAIM_given_name=<!--#echo var="OIDC_CLAIM_given_name" --><br/>
OIDC_CLAIM_family_name=<!--#echo var="OIDC_CLAIM_family_name" --><br/>
</p>
<p>
OIDC_CLAIM_locale=<!--#echo var="OIDC_CLAIM_locale" --><br/>
</p>
<p><a href="/oidc/redirect_uri?session=logout">ログアウト</a></p>
</body>
</html>
動作確認
再度ブラウザで動作確認画面を開くと、メールアドレス、アカウントに設定した画像、氏名などが表示されることが確認できました。
なお、d アカウント・コネクトに戻す(etc/apache2/sites-available/example.com-ssl.conf
を元に戻して apache2 再起動する)と、REMOTE_USER 以外の情報は全く得られないことがわかります。両者で共通して得られるのは REMOTE_USER (つまり、iss クレームと sub クレーム)だけですね。
次回
本記事「3. Google アカウント編」では、d アカウント・コネクトではなく Google アカウントでソーシャルログインできるようにしてみました。次の記事は「4. マルチプロバイダ編」として d アカウント・コネクトと Google アカウントの両方でソーシャルログインできるようにします。