mod_auth_openidcによりApache HTTP ServerをOpenID Connect Relying Partyにする

こんにちは、滝澤です。

Apache HTTP ServerをOpenID Connect Relying Partyにするmod_auth_openidcというモジュールを使ってみる機会がありましたので、本記事で情報共有します。

なお、記事が長くなったので本編と設定例である3編に分けました。

本記事では本編として、mod_auth_openidcの概要とmod_auth_openidcの導入方法を紹介します。

OpenID Connectとは

OpenID Connectについてはここでは特に詳しくは説明しませんが、いくつか説明やサイトを紹介します。

OpenID Connect Core 1.0 日本語訳によると次のように説明されています。

OpenID Connect 1.0 は, OAuth 2.0 プロトコルの上にシンプルなアイデンティティレイヤーを付与したものである. このプロトコルは Client が Authorization Server の認証結果に基づいて End-User のアイデンティティを検証可能にする. また同時に End-User の必要最低限のプロフィール情報を, 相互運用可能かつ RESTful な形で取得することも可能にする.

OpenID Foundationによる「OpenID Connect FAQ and Q&As」による次の説明が一番簡潔に説明していると思います。

(Identity, Authentication) + OAuth 2.0 = OpenID Connect

認可フレームワークである"OAuth 2.0"に"Identity"と"Authentication"(認証)を加えたものが"OpenID Connect"であるということです。

OpenID Connectについては、Nov Matake氏による次の記事が参考になると思います。

また、Kawasaki Takahiko氏による次のエントリーも参考になると思います。

なお、本記事ではOAuth 2.0およびOpenID Connectの用語については特に説明なしに使用しますのでご了承ください。説明するだけで一つの記事ができあがってしまいますので。

用語については先の記事および次の文書が参考になると思います。

mod_auth_openidc

mod_auth_openidcはApache HTTP Server(以降、apacheと略す)用の認証・認可のモジュールです。 apacheに組み込むことでOpenID Connect Relying Party (RP)として動作するようになります。また、OAuth 2.0 Resource Serverとしても動作することができます。

開発者はZmartZone IAM社のCTOのHans Zandbelt氏です。シングルサインオン製品などを開発しているPing Identity社に在籍していたころに開発が始まり、現職のZmartZone IAM社によりサポートが行われています。

また、mod_auth_openidc 2.3.1がRelying PartyとしてOpenID Certificationを取得しています。

mod_auth_openidcモジュールをApache HTTP Serverに組み込み、OpenID Connect Relying Partyとして設定すると、以下のことが可能になります。

  • シングルサインオン
  • 認証したユーザーのユーザーIDの取得、および環境変数REMOTE_USERとしての利用
  • 氏名やメールアドレスなどのプロフィール情報の取得
  • 取得したプロフィール情報の環境変数としての利用
  • リバースプロキシーとして動作する場合は、取得したユーザーIDとプロフィール情報をバックエンドへのリクエストのHTTPヘッダーとして追加

認証機能を持っていないサイトがこれにより認証を行うことができるようになりますし、ベーシック認証のようなapacheでの認証を行っていたサイトはこれに置き換えることにより、シングルサインオンができるようになります。

検証環境

検証環境は以下の通りです。

  • CentOS 7.3
  • mod_auth_openidc 2.3.1 (mod_auth_openidc-2.3.1-1.el7)
  • Apache HTTP Server 2.4.6 (httpd-2.4.6-45.el7)
  • Redis 3.2.3 (redis-3.2.3-1.el7)

組織内の認証・認可の用途として、G SuiteやAzure ADのアカウントと連携した例を紹介します。

インストール方法

apacheがインストールされている前提で手順を紹介します。

mod_auth_openidcのリリースページからcjoseとmod_auth_openidcのRPMパッケージをダウンロードします。

$ curl -L -o cjose-0.5.1-1.el7.centos.x86_64.rpm https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.3.0/cjose-0.5.1-1.el7.centos.x86_64.rpm
$ curl -L -o mod_auth_openidc-2.3.1-1.el7.centos.x86_64.rpm https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.3.1/mod_auth_openidc-2.3.1-1.el7.centos.x86_64.rpm

依存するパッケージとしてredisとhiredisをインストールします。共にFedora EPELリポジトリで提供されているため、EPELリポジトリの登録がなければ、epel-releaseパッケージを先にインストールします。 なお、提供されているmod_auth_openidcパッケージはキャッシュのストレージとしてRedisを使うことができるようにビルドされています。

$ sudo yum install epel-release
$ sudo yum install redis hiredis

先ほどダウンロードしてきたcjoseとmod_auth_openidcパッケージをインストールします。なお、依存により、jansson, openssl, pcre, curlといったパッケージもインストールされていなければインストールされます。

$ sudo yum install cjose-0.5.1-1.el7.centos.x86_64.rpm mod_auth_openidc-2.3.1-1.el7.centos.x86_64.rpm

mod_auth_openidcパッケージのインストールが完了したら、mod_auth_openidcが提供しているファイルやディレクトリを次のようにして確認してみましょう。

$ rpm -ql mod_auth_openidc
/etc/httpd/conf.modules.d/10-auth_openidc.conf
/usr/lib64/httpd/modules/mod_auth_openidc.so
/usr/share/doc/mod_auth_openidc-2.3.1
/usr/share/doc/mod_auth_openidc-2.3.1/ChangeLog
/usr/share/doc/mod_auth_openidc-2.3.1/LICENSE.txt

ここで、mod_auth_openidc.soがmod_auth_openidcのモジュールです。

さらに、10-auth_openidc.confというファイルには次のようにモジュールをロードする設定が記述されています。

LoadModule auth_openidc_module modules/mod_auth_openidc.so

mod_auth_openidcパッケージには設定のサンプルファイルが含まれていないため、リポジトリからダウンロードして配置します。

$ curl -L -o auth_openidc.conf https://raw.githubusercontent.com/pingidentity/mod_auth_openidc/master/auth_openidc.conf
$ sudo cp auth_openidc.conf /etc/httpd/conf.d/

複数のOP(OpenID Provider)に対応する場合には、メタデータ用のディレクトリを作成します。このディレクトリはapacheの実行権限でファイルの読み書きができる必要があります。

$ sudo mkdir -m 0700 /var/cache/httpd/mod_auth_openidc /var/cache/httpd/mod_auth_openidc/metadata
$ sudo chown -R apache:apache /var/cache/httpd/mod_auth_openidc
$ sudo ls -ld /var/cache/httpd/mod_auth_openidc/metadata
drwx------. 2 apache apache 6 Aug  2 03:52 /var/cache/httpd/mod_auth_openidc/metadata

キャッシュのストレージとしてRedisを使う場合は、/etc/redis.confの設定を行い、Redisのサービスを起動させます。

$ sudo systemctl enable redis.service 
$ sudo systemctl start redis.service

以上で、インストールは完了です。

なお、JSONデータの処理プログラムであるjqコマンドを用意しておくと設定時の作業やデバッグ時に便利なのでインストールしておきましょう。

$ sudo yum install jq

設定例

設定例として次の3つを用意しましたので、ご興味のある記事をご覧ください。

動作確認

Google編」で示した、OP(OpenID Provider)としてGoogle(G Suite)を利用する場合の設定を行った際の動作確認について説明します。

ウェブブラウザで動作確認用のサイトにアクセスすると、OpenID Connectによる認証・認可の処理が行われます。

Google (G Suite)で認証済みでなければ、Googleのログインページにリダイレクトされるのでログインの操作を行います。

認証済みのユーザーの場合、あるいはログインが完了すると次のようなページが表示されます。

サイト画面

配置したhtmlファイルにSSIで次のような変数を埋め込んでいるため、ユーザーのプロフィール画像と名前とユーザーIDが表示されます。

変数説明
OIDC_CLAIM_pictureclaimのメンバーとして取得できるpictureの値(エンドユーザーのプロフィール画像のURL)
OIDC_CLAIM_nameclaimのメンバーとして取得できるnameの値(エンドユーザーのフルネーム)
REMOTE_USERユーザーID

これにより、プロフィール情報が取得されていること、および、ユーザーが認証されていることがわかります。

Logoutのリンクをクリックすると、セッション情報が削除され、ログアウト後のページに遷移します。

ログアウト

このときのアクセスログは次のようになり、ユーザーID「takizawa」が記録されているのがわかります。

192.0.2.80 - - [09/Aug/2017:06:49:46 +0000] "GET / HTTP/1.1" 302 663 "https://example.com/loggedout.html" "-"
192.0.2.80 - takizawa [09/Aug/2017:06:49:51 +0000] "GET /redirect_uri?state=〜略 HTTP/1.1" 302 217 "-" "-"
192.0.2.80 - takizawa [09/Aug/2017:06:49:51 +0000] "GET / HTTP/1.1" 200 351 "-" "-"
192.0.2.80 - - [09/Aug/2017:06:49:53 +0000] "GET /redirect_uri?logout=http%3A%2F%2Fexample.com%2Floggedout.html HTTP/1.1" 302 231 "https://example.com/" "-"
192.0.2.80 - - [09/Aug/2017:06:49:53 +0000] "GET /loggedout.html HTTP/1.1" 200 159 "https://example.com/" "-"

まとめ

apacheにmod_auth_openidcモジュールを組み込むことにより、RPとして動作することが確認できました。

また、アクセスしたユーザーのユーザーIDを記録することができ、さらに、取得したユーザーIDやプロフィール情報を変数として利用することができることを確認しました。

参考サイト

株式会社ハートビーツのインフラエンジニアから、ちょっとした情報をお届けします。