OAuth2.0/OpenID Connectの利用(3) : OpenAMでOPを立ててmod_auth_openidcと連携する

# はじめに
第3回として、OpenID Connectのopenid provider(OP)をOpenAMで立ててみようと思います。
連携先のrelying party(RP)はmod_auth_openidcを使ってOPとのやり取りを楽しようと思います。
mod_auth_openidcはApacheのモジュールとして動作し、RPの機能を提供します。

# mod_auth_openidcの設定
mod_auth_openidcはCentOS7にインストールします。
まずは、必要なパッケージをインストールしてください。

```
# yum install -y httpd mod_ssl mod_php
```

次にmod_auth_openidcのパッケージをインストールします。
今回は弊社で提供しているパッケージの手順を記載します。

```
# cd /home/osstech/
# tar xvf osstech-mod_auth_openidc-2.3.10.2-1.el7.tar.gz
# cd osstech-mod_auth_openidc-2.3.10.2-1.el7
# ./install.sh
```

mod_auth_openidcのパッケージがインストール出来たら、
設定ファイルを作成します。

```
# cd /etc/httpd/conf.d
# vi openidc.conf
```

下記の内容を編集してください。

```
<VirtualHost *:443>

    SSLEngine On
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

    ServerName oidcrp.test.osstech.co.jp

    OIDCProviderMetadataURL https://sso.test.osstech.co.jp:443/openam/oauth2/.well-known/openid-configuration
    OIDCClientID modauthopenidc
    OIDCClientSecret password
    OIDCResponseType "code"
    OIDCRedirectURI https://oidcrp.test.osstech.co.jp/auth/
    OIDCCryptoPassphrase passphrase
    OIDCProviderTokenEndpointAuth client_secret_basic
    OIDCScope "openid profile email"
    OIDCSSLValidateServer Off
　　#OIDCPKCEMethod S256

    <Location />
        AuthType openid-connect
        Require valid-user
        #LogLevel debug
    </Location>

</VirtualHost>
```

設定内容を簡単に説明します。
以下の3行はこのサーバのSSL設定です。
SSLEngine On
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

|パラメータ名|説明|
|---|---|
| OIDCProviderMetadataURL | OPのメタデータURL。OpenAMのOpenID Connectのデフォルト設定URLを記載します。 |
|OIDCClientID|クライアントID|
|OIDCClientSecret|クライアントのクレデンシャル|
|OIDCResponseType|レスポンスタイプ。code,token,id_tokenとその組み合わせになります。ここではcodeを指定して、Authorizationコードフローを要求しています。
|OIDCRedirectURI|OPからRPへのリダイレクトURLです。このサーバでmod_auth_openidcがOIDCを処理するURIです。Apacheのドキュメント配下の任意のURIにします。|
|OIDCCryptoPassphrase|mod_auth_openidc が暗号化を行う際に使用するパスフレーズで、ランダムな値を設定します。|
|OIDCProviderTokenEndpointAuth|エンドポイントの認証方法で、client_secret_basicを指定しています。OP(OpenAM)のエンドポイントに指定したクライアントIDとクレデンシャルの値をベーシック認証でアクセスします。|
|OIDCScope|openid,email,profileなどのスコープを指定します。|
|OIDCSSLValidateServer|Offを指定して、OP(OpenAM)のSSL証明書は検証しません。検証する場合はあらかじめOPの証明書をCentOS上に配置してください。|
|OIDCPKCEMethod|s256,plainを指定します。このディレクティブがあるとPKCEの拡張フローを実施します。code_challengeとcode_challenge_methodを認可コードのリクエストでOPに送信します。アクセストークンのリクエストでcode_verifierをOPに送信して認可コードの検証をおこないます。code_verifierからcode_challengeを生成する方法でs256はSHA256のハッシュでplainはそのままです。|

以下の行でApacheのドキュメントルート配下をすべて、OpenID Connectで認証済みのユーザのみアクセス可能と求します。
&lt;Location /&gt;
    AuthType openid-connect
    Require valid-user
    #LogLevel debug
&lt;/Location&gt;
※LogLevel debugのコメントアウトを外すとApacheのエラーログにid_tokenの値など詳細な情報を確認できます。

Apacheのドキュメントルートに環境変数を表示するPHPスクリプトを作成します。

```
# vi /var/www/html/index.php
```

下記の内容を編集してください。

```
<?php
echo "<table>";
foreach (getallheaders() as $name => $value) {
    echo "<tr><td>$name: $value</td></tr>";
}
echo "</table>";
?>
```

最後にApacheの再起動と自動起動設定をします。

```
# systemctl restart httpd
# systemctl enable httpd.service
```

以上でmod_auth_openidcの設定は完了です。

# OpenAMの設定
※弊社製品のOpenAM13のバージョンで設定をしています。

##　OpenID Connectのプロバイダ設定作成

ますはじめに、OIDCプロバイダを作成します。
OpenAMの管理コンソールにアクセスして、ダッシュボードの[OAuthの設定]をクリックします。
![openam_oauth1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/d6f962ec-5dd2-f0cd-c3a3-7d7fe3a89537.png)

次に[OpenID Connectの設定]をクリックします。
![openam_oauth2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/c12c96bf-c0d0-24af-b6f2-9994d0a7e85d.png)

OpenID Connectのパラメータ設定画面が表示されます。
ここではデフォルト値のままで右上の[作成]を押します。
![openam_oauth3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/f52d8543-0c66-188f-6692-127f536e4e59.png)

左ペインの[サービス]のリンクを押すと、[OAuth2 プロバイダ]のリンクが追加されています。
![openam_oauth4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/477c6248-ed7e-c9ec-b334-f3e72b90ba9f.png)

このリンクを押すとOpenID Connectに関する詳細なパラメータを変更することが出来ます。
![openam_oauth5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/cb04d173-2972-c547-ed3f-33006db15921.png)

##　mod_auth_openidcのクライアント登録

次にOIDCクライアントを登録します。
左ペインの[エージェント]をクリックします。続けて下部に表示される[OAuth2.0のクライアント]タブをクリックします。
エージェントの[新規]をクリックします。
![openam_oauth6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/577bbab5-741b-a922-e94d-efdeda4504e9.png)

クライアントの作成画面が表示されるので、mod_auth_openidcで設定したクライアントIDとクレデンシャルを入力して、[作成]をクリックします。
![openam_oauth7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/48874198-cedc-f798-23c5-53ff782764f2.png)

作成したクライアントがエージェントの一覧に追加されているのでそのリンクをクリックします。
![openam_oauth8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/1199f437-e701-e89b-2300-ef63abfc59f9.png)

パラメータ設定で変更する箇所を説明します。
まず、[リダイレクトURI]の[新しい値]にmod_auth_openidcで設定したOIDCRedirectURIの値を入力して[追加]を押してください。
追加されると[現在の値]のボックスに表示されます。
![openam_oauth9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/b1a3e814-1c07-5cf0-6772-c14d565d2aca.png)

続いて[スコープ]に同様な手順で、「openid」、「profile」、「email」を追加してください。
![openam_oauth10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/dac94111-1b4e-0b28-8ab8-d8cd88d869a2.png)

続いて[クレーム]に同様な手順で、「given_name|名前」、「family_name|姓名」、「name|ユーザー」、「email|メールアドレス」を追加してください。
![openam_oauth11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/e76003d2-490e-a648-7399-a41814a072b3.png)

続いて[クライアントの表示名]に、「mod_auth_openidcクライアント」、[クライアントの説明]に、「OpenID Connectテストクライアント」を追加してください。
![openam_oauth12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/9330ac0f-27b8-a6a4-404d-2823a7e15111.png)

その他はデフォルト値で、上部の[保存]をクリックして設定を保存します。
![openam_oauth13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/cd210ea1-6af9-a103-c1b6-87da8affd9c3.png)

これでOpenAMの設定は完了です。
今回は既に認証モジュールとデータストアにはOpenLDAPを設定してあり、IDパスワード認証をしてログインします。
第1回で利用したFacebook向けの認証モジュールでログインすることも可能です。

# いよいよ、動作確認

ブラウザから、mod_auth_openidcが動作しているApacheのドキュメントルートにアクセスします。
![firefox1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/cda50d27-1642-cd0a-d0ee-d9d6a727669d.png)

OpenAMのログイン画面にリダイレクトするので、OpenLDAPに存在するユーザーのIDとパスワードを入力してログインを押します。
![firefox2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/98b3ae0a-c816-035f-caee-3ab37ed511fd.png)

続いてユーザプロファイルの送信同意画面が表示されるので、Allowを選択してください。
![firefox3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/0624e4b6-fd3d-6e0a-9f99-b34482d5bd8b.png)

mod_auth_openidcが動作しているApacheのドキュメントルートに戻り、
Apacheの環境変数が表示されています。
![firefox4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316107/2c60be09-1c06-fbcb-757c-ecb3b55ec361.png)

IDトークンで渡ったクレームの情報が数多く表示されているかと思います。
これで動作確認は終了です。

# おわりに
今回はOpenAMをOPとして利用して、IDトークン、アクセストークンの発行や
UserInfo APIでRPにユーザ情報の提供を行いました。
RPとしてApacheのモジュールのmod_auth_openidcを利用しましたが、このApacheをリバースプロキシとして、
構成すればバックエンドのアプリケーションサーバにも簡単に認証連携が出来るようになります。
第1回、第2回、第3回でOpenAMをOP,RPとして動作する手順を記載いたしました。
次回はOpenID Connectの仕様について少し解説していきたいと思います。