OpenAMからApacheにOpenID ConnectでFederationする

## 今日やること

昨日はOpenID ProviderとなったOpenAMにRelying Partyの登録をしました。そして、実際にFederationのためのエンドポイントをたたいて、ID Tokenを取得し、どういった情報が伝搬されるかの確認を行いました。

今日は実際にRelying Partyをセットアップし、OpenID ProviderからFederationしましょう。

## OpenID Connect関連のライブラリ

OpenID Connectにおける、OpenID ProviderやRelying Partyを実装する上で、役に立つライブラリやプロダクト、ツールが[openid.net](http://openid.net/developers/libraries/)で公開されています。

<img width="599" alt="001.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/ca060b14-31f8-b652-5454-3b04554cc81c.jpeg">

そのライブラリがRelying Partyになるのか、OpenID Providerになるのか、実装できる環境・言語についての記載があります。この中から今日は**Apache HTTP Server**にインストールできる**Apache mod_auth_openidc**を使ってみたいと思います。

## Apache mod_auth_openidc

Apache mod_auth_openidcの概要は以下の通りです。

* mod_auth_openidcは、OpenID Providerに対し、ユーザーを認証するApache HTTP Server向けのモジュール
* このモジュールを使用すると、Apache HTTP ServerをRelying PartyとしてOpenID Connect Providerに接続できる
* OpenID Providerに対してユーザーを認証し、OPから連携されるID Tokenを使って、アイデンティティ情報をApache上にデプロイされているアプリケーションに渡すことができる

## OpenAM(OpenID Provider)にRelying Partyを登録する

[昨日の記事](http://qiita.com/nanazero/items/56d6bc70b7348dce1aca#openam%E3%81%ABrelying-party%E3%82%92%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B)を参考に以下のパラメータでRelying Partyを登録します。

| param name | value | desc |
|:--|:--|:--|
|名前|relyingparty|client id。後でApacheの設定に入れる。|
|パスワード|password|client secret。後でApacheの設定に入れる。|
|リダイレクトURI|https://rp.example.com:443/cb|コールバックのURIを指定する。後でApacheの設定に入れる。|
|スコープ|openid profile|前回と同じ値。後でApacheの設定に入れる。|
|Token Endpoint Authentication Method|client_secret_post|ID Token要求時のClient認証のやりかた|

Token Endpoint Authentication Methodはmod_auth_openidcの仕様上、設定する必要があります。

## Apacheにmod_auth_openidcをインストールする

### 環境

今回、ApacheをホストするOSは以下のものを使います。

* OS
    - CentOS 7.2 (Vagrant)
* Memory
    - 512MB
* FQDN
    - rp.example.com

今回、CentOS 7系にしている理由は、mod_auth_openicの関連ライブラリのRPMがYUMリポジトリに存在しないからです。ソースからビルドすれば、CentOS 6系でもセットアップできます。

### 事前準備

mod_auth_openidcをインストールする前にepelのリポジトリを追加します。

```bash
$ sudo yum -y install epel-release
```

続いてApache HTTP Serverをインストールします。

```bash
$ sudo yum -y install httpd httpd-devel mod_ssl
```

Relying PartyはOpenID Provider(OpenAM)のエンドポイントを認識する必要があるので、名前解決をできるようにしておきます。

```bash
$ sudo diff /etc/hosts{,.org}
3,4d2
< 192.168.33.10 iam.example.com
< 192.168.33.50 rp.example.com
```

### 依存ライブラリのインストール

mod_auth_openidcをインストールするにあたり、依存ライブラリが結構あります。
epelのリポジトリを追加していれば、ほとんどがyumコマンドでインストールすることができます。

```bash
$ sudo yum -y install jansson jansson-devel
$ sudo yum -y install openssl openssl-devel
$ sudo rpm -ivh https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.1.0/cjose-0.4.1-1.el6.x86_64.rpm
$ sudo yum -y install hiredis hiredis-devel
```

### mod_auth_openidcのインストール

それでは、mod_auth_openidcのインストールを行います。
github上にRPMも公開されていますので、これを使ってインストールします。
この記事を執筆時点のバージョンは`release 2.1.2`となっています。

```bash
$ sudo rpm -ivh https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.1.2/mod_auth_openidc-2.1.2-1.el7.centos.x86_64.rpm
Retrieving https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.1.2/mod_auth_openidc-2.1.2-1.el7.centos.x86_64.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:mod_auth_openidc-2.1.2-1.el7.cent################################# [100%]
```

Apacheのmodulesディレクトリに追加されていることを確認します。

```
ls -ltr /etc/httpd/modules/mod_auth_openidc.so 
-rwxr-xr-x 1 root root 1114382 Nov 19 12:56 /etc/httpd/modules/mod_auth_openidc.so
```

### Apacheの設定ファイルの作成

続いて、mod_auth_openidcの設定情報をApacheに追加していきます。
設定項目が多いように感じますが、基本的にはOpenID Provider(OpenAM)に登録したRelying Partyのパラメータです。
ちょっと補足をしますと、`OIDCSSLValidateServer`はOpenID Provider(OpenAM)のサーバー証明書がオレオレ証明書の場合、`Off`にする必要があります。加えて、`Location`ディレクティブはコンテキストルート以下のアクセスはID Tokenの検証が成功しないとできませんという設定です。

```apache
$ sudo cat /etc/httpd/conf.d/openidc.conf 
LoadModule auth_openidc_module modules/mod_auth_openidc.so
OIDCProviderMetadataURL https://iam.example.com:443/openam/oauth2/.well-known/openid-configuration
OIDCClientID relyingparty
OIDCClientSecret password
OIDCRedirectURI https://rp.example.com:443/cb
OIDCCryptoPassphrase passphrase
OIDCScope "openid profile"
OIDCSSLValidateServer Off
<Location />
  AuthType openid-connect
  Require valid-user
</Location>
```

設定完了後、Apacheを再起動します。

```bash
$ sudo systemctl start httpd.service
```

## 動作確認

それでは動作確認をしていきます。
確認にあたって、Relying Party上に`phpinfo()`をコンテンツとして配置しておくと、認証済みユーザーの属性が連携され、アプリケーションで利用可能な状態になっていることが分かりやすくなると思います。

こんな感じで、phpinfo()を置いておきます。

```bash
$ sudo yum -y install php
$ cat /var/www/cgi-bin/phpinfo.php
<?php
phpinfo();
?>
$ chmod +x /var/www/cgi-bin/phpinfo.php
$ sudo systemctl start httpd.service
```

ブラウザを立ち上げて、Relying Party上の`phpinfo()`（本記事では`https://rp.example.com/cgi-bin/phpinfo.php`）にアクセスしてみましょう。

認可リクエストがOpenID Provider(OpenAM)に送信され、認証画面が表示されます。ここでは、本連載の検証用アカウント（ユーザー名は`johnd`）でサインインします。

<img width="313" alt="002.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/6a73fff6-2c41-521b-97a3-07f95b3729ab.jpeg">

Federationの同意画面が表示されます。内容を確認して、同意します。

<img width="550" alt="003.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/82c8d252-d1cc-1b45-313c-3f948334ae02.jpeg">

Relying Partyに返って、`phpinfo()`が実行されます。
**HTTP Headers Information**を見てみると、Federationされたユーザーの属性情報などが、HTTP Headerにセットされていることが確認できます。

<img width="406" alt="004.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/06847c43-da9b-2647-2b19-f07c212a35db.jpeg">

きれいに連携できてますね！

## 〆

本日のまとめとしては

* openid.netにRelying Partyの実装を支援するライブラリがおいてある
* mod_auth_openidcはApache HTTP ServerのためのRelying Partyモジュール
* RPMでgithub上に公開してあるから、あっさりインストールできる
* Federationされたユーザーの属性情報はHTTP Headerにセットされている

こんなとこでしょうか。
明日は何しよう～(´ρ`)

ばい！