Webサイトにログイン画面を追加する

OpenID Connectを使ってWebサイト(Apache)にログイン画面を追加するという事なのですが、思いのほか手順としてまとまった記事が無かったため、まとめておこうと。
OpenID Connect(OIDC)とは、とかの説明は読んでて頭痛くなる話でありますので割愛。動けば正義。

本記事ではOIDCプロバイダーを作り、ログイン画面としてそれを使うようにApacheを構成し、エンドユーザーがWebサイトで自身のユーザーIDをサインアップ、ログインするまでを手順を追って説明します。

OIDCプロバイダーとしてはIBM CloudのApp IDで説明しますが、いわゆるOIDCプロバイダーなら何でも似たようなことが出来るはず。

# IBM CloudのApp IDサービスを作る

１．IBM Cloudのカタログで「App ID」で検索し、サービスを作る。
ライトプランを使用。1000回ログイン、1000ユーザーまではタダ。
https://cloud.ibm.com/catalog
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/4b631f2c-2819-8873-2509-a3ba833ac6d7.png)

２．サービスが出来たら、その管理画面で「認証の管理」を開く。IDプロバイダーとして「クラウド・ディレクトリー」以外は無効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/057bff83-03ca-9b15-40d1-dd220abe8869.png)

３．同じ画面の「認証設定」タブを開き、WebリダイレクトURLを追加する。後に構成するWebサーバーのアドレスと、リダイレクト確認用に使われるページを指定する。
例では「```http://www.example.com/redirect_uri```」。
なおこのURLは、ページが実在する必要はない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/1ede548c-0c52-6664-432a-67cc14ea599f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/d02ab7a0-af00-cdc8-f4b1-eff0a48cf5e3.png)

４．「サービス資格情報」を開き、資格情報を追加する。
「リーダー」で結構。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/a81d90bd-6fa2-9262-9bda-fc93353c6921.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/84fb03fc-01fd-2be5-3345-97db0f170d3f.png)

５．作られた資格情報の内容を確認する。
以下情報の内、"clientId"、"discoveryEndpoint"、"secret"は後のApacheの構成で使用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/6044ab26-d097-f8a8-abe8-e9bd809bf88c.png)

# Webサーバーを作る
１．仮想サーバーを作る。
Webサーバーはインターネットからアクセス出来れば何でもいいのだが、Amazon Lightsailを使うか。$3.5でOSがCentOS 7の仮想サーバーを一台作る。
https://aws.amazon.com/jp/lightsail-vps/

一応サーバーのFQDNは先に設定したリダイレクトURLに合わせたもの（```www.example.com```）をRoute 53に登録する。ここの手順は割愛。

２．Apacheをインストールする。
Webサーバーにsshでログインし、Apache httpdとmod_auth_openidc、あと便利のためphpをインストールする。

```
$ sudo -i
# yum install -y httpd
# yum install -y mod_auth_openidc
# yum install -y php
```

３．ApacheにOpenID Connectの設定を追加する。
とりあえずWebサイト全体(/)を認証必要な様に設定する。
以下のファイルを作成する。
「OIDCProviderMetadataURL」は先の"discoveryEndpoint"、「OIDCClientID」は"clientId"、「OIDCClientSecret」は"secret"である。
「OIDCRedirectURI」は先に設定したリダイレクトURL、「OIDCCryptoPassphrase」は適当な文字列を指定する。

```:/etc/httpd/conf.d/oidc.conf
OIDCProviderMetadataURL https://jp-tok.appid.cloud.ibm.com/oauth/v4/36c8a54c-b690-4279-a5d3-7ddd64dd73fb/.well-known/openid-configuration
OIDCClientID 2edc690f-6876-4cf2-aad9-64629869d533
OIDCClientSecret YWYwOTg3MDUtZjhiNS00ZjMyLTgzOTgtN2NjNDdlZWYyMjhh

OIDCRedirectURI http://www.example.com/redirect_uri
OIDCCryptoPassphrase xxxxxxxx

<Location />
   AuthType openid-connect
   Require valid-user
</Location>

```

４．index.htmlを作る。

```html:/var/www/html/index.html
<!DOCTYPE html>
ログイン成功！
```

５．Apacheを起動する。

```
# systemctl enable httpd
# systemctl start httpd
```

# エンドユーザーとしてWebサーバーにログインする
Webサーバーが起動したら、エンドユーザーとして「ログインアカウントのサインアップ」、「サインアップ確認用電子メールの確認」、「ログイン」までを試してみる。
ユーザーアカウントは電子メールアドレスを使うため、何だったらgmailにテスト用のメアドを作っておく。

１．Webサーバーにアクセスする。
Webブラウザを利用し、作ったWebサーバーのFQDN（ここでは「```http://www.example.com/```」）にアクセスする。

以下の様な画面が表示されただろうか。Webサーバーにログイン画面が追加されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/9fbaba6e-86aa-87f6-c854-eea15ebc48c8.png)

２．Webサイトにサインアップする。
先のログイン画面の下、「Sign up!」をクリックすると表示される以下の画面で、電子メールアドレスとパスワードを入力し、「Sign up」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/52ca8880-3c3f-fd10-977f-d1066d260ac5.png)

３．サインアップ確認用の電子メールを確認する。
以下の画面が表示されたら、登録したメアドのメールボックスを確認し、サインアップ確認用の電子メールが届いているのを確認し、メール中の「Veryfy」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/17cabaf1-ab10-1e52-f2ab-282b46fe134c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/445a8b8b-c7b8-b11d-f211-00b41a5ea585.png)

４．確認が終わったら、再度Webサーバー（```http://www.example.com```）にアクセスする。
やはりログイン画面が表示されるので、サインアップした電子メールアドレス、パスワードでログインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/ce16732b-a085-5915-7a57-80f8ad9c0809.png)

５．ログイン成功を確認する。
先に作成したindex.htmlのページが表示されただろうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/8fb3ccd5-585c-34a0-f80f-5e386c324ccd.png)


# （ついで）Webサーバーから見える環境変数
ついでだが、OIDCログインされた状態でWebサーバーにアクセスする際、Webサーバー側ではどのような情報が見えるのかを確認したい。先ほど導入して使っていないphpをここで使う。

１．phpinfoを表示するページを作る。

```php:/var/www/cgi-bin/phpinfo.php
<?php
phpinfo();
?>
```

２．Webブラウザで「```www.example.com/cgi-bin/phpinfo.php```」にアクセスする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/b201c8e9-6359-f5c9-a45c-3f75581c2b52.png)

特に、Apache Environmentで表示される内容が重要である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/e60154a9-b93f-f04e-51b8-e4467b1b3ff8.png)

OIDC_access_tokenの値が、いわゆるJWTというもので、今回は設定していないが、デコードすればユーザーに付与されたロールや属性などの情報が手に入り、Webアプリ側でのアクセス制御等に利用する事が出来る。


# （ついで２）ユーザー管理
OIDCプロバイダーを使う大きな意義は、ユーザーIDの保管や、サインアップ、パスワードリセット等の機能をWebサーバーの作りからほとんど分離して移管できるところにある。とはいえ誰が登録しているのかは知りたいので、App IDの画面から登録ユーザーの一覧を確認することが出来る。

IBM CloudのApp ID画面を開き、「認証の管理」＞「クラウド・ディレクトリー」＞「ユーザー」を開けば、登録されているユーザーの一覧を確認することが出来る。
ちなみに、ここから予めユーザーを作っておくという事も出来る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/9bab4c58-28df-5800-3892-21d8582d2b80.png)

個別のユーザー登録情報を開けば、そのユーザーに設定されている役割や、カスタム属性等を表示、編集できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/05a80198-7b9a-1ab1-6894-b48075378523.png)

そういや、Keycloakでは出来る、管理者によるユーザーのパスワードリセットはApp IDでは出来ないんだな。。パスワードリセットはユーザー自身で行えば良いというのは、セキュリティ的に正しいとは思うが。API使えば出来たりするのか。

（次回）サインアップしたユーザーアカウントを使ってREST-APIにログイン認証機能を付加する。
https://qiita.com/rk05231977/items/0b77d23d1f44cf9ad6ae