Cloud IAPを使ってWebアプリのフロントにGoogle認証ページを設ける

# Cloud IAPとは
Google Cloud Platformのサービスのひとつで、Googleアカウントを用いた認証のゲートウェイを構築できるサービスです。Google App EngineやGoogle Compute Engine、Google Kubernetes Engineのフロントに設置することで、これらのWebアプリケーションのフロントにGoogleアカウント認証のページを設置することができます。
参考: https://cloud.google.com/iap/docs/concepts-overview#how_iap_works

本記事では、Google Kubernetes EngineでWebアプリケーションを構築し、そのフロントにCloud IAPを設置するまでの手順をまとめています。

# 完成イメージ
## 認証未登録ユーザでは
![Feb-13-2019 00-27-05.gif](https://qiita-image-store.s3.amazonaws.com/0/315248/28b6fa5c-179c-f69b-3fff-9af07a346123.gif)
Googleアカウントログインページへ自動で遷移、ログインするもエラーで弾かれる

## 認証登録済ユーザでは
![Feb-13-2019 00-32-19.gif](https://qiita-image-store.s3.amazonaws.com/0/315248/ac870558-c438-c307-7a34-cec534ffc4c9.gif)
Googleアカウントログインページへ自動で遷移、ログイン後にWebアプリケーションにアクセスできる

# 前提条件
* ドメインを所有していること

# 手順
## 1. GKEクラスタを作成
![1.png](https://qiita-image-store.s3.amazonaws.com/0/315248/2edbaafc-0e77-014a-afe7-8c0df1de0900.png)
画面左上のハンバーガーメニューをクリックし、 `Kubernetes Engine` → `クラスタ` を選択します
![2.png](https://qiita-image-store.s3.amazonaws.com/0/315248/0df7af78-f084-84f8-a8dc-7016c41f4963.png)
`クラスタを作成` をクリックします
![3.png](https://qiita-image-store.s3.amazonaws.com/0/315248/b9be957f-138b-d30c-e291-adcba26ba054.png)
適当な値を入力し、 `作成`　をクリックします

以降の操作をCloud Shellで行うため、以下の操作を行います
![4.png](https://qiita-image-store.s3.amazonaws.com/0/315248/389f12a5-12f8-9068-d8fa-31e795d85e1b.png)
1.で作成したクラスタの `接続` をクリックします
![5.png](https://qiita-image-store.s3.amazonaws.com/0/315248/56810b6c-cd13-687d-7080-b8c21da5fcb7.png)
`Cloud Shellで実行` をクリック
![6.png](https://qiita-image-store.s3.amazonaws.com/0/315248/b008e648-5818-76bb-5b1e-462874d2892d.png)
下部に表示されるCloudShellに自動でコマンドが入力されるので、そのままEnterを押下して実行します

## 2. pod, deployment, serviceを作成
以下コマンドをCloud Shell上で実行し、サンプルWebアプリケーションのpodとdeployment、そしてserviceを作成します

```shell:podとdeploymentを作成するコマンド
kubectl run web --image=gcr.io/google-samples/hello-app:1.0 --port=8080
```
```shell:serviceを作成するコマンド
kubectl expose deployment web --target-port=8080 --type=NodePort
```

## 3. ingressの作成
### 3-1. 公開鍵・秘密鍵の作成
以下コマンドをCloud Shell内で実行し、ingressのHTTPS通信に用いる公開鍵・秘密鍵を作成します

```shell:公開鍵・秘密鍵を作成
openssl genrsa 2048 > server.key
openssl req -new -key server.key > server.csr
openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
```

### 3-2. 公開鍵・秘密鍵の登録
以下コマンドをCloud Shell内で実行し、3-1.で作成した鍵をingressで利用できるようにするためにKubernetesのsecretとして登録します

```shell:鍵をsecretへ登録
kubectl create secret tls secret --key server.key --cert server.crt
```

### 3-3. ingressの作成
以下の内容のyamlファイルを作成します

```yml:ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
    name: ingress
    annotations:
        kubernetes.io/ingress.allow-http: "false" # http接続を許容しない場合はfalseを指定
        kubernetes.io/ingress.global-static-ip-name: "ingress-ip" # 静的IPを割り当てる場合は名前を指定(事前にIPを予約する必要あり)
    labels:
        app: ingress
spec:
    tls:
    - secretName: secret
    backend:
        serviceName: web
        servicePort: 8080
```

作成したマニフェストファイルに対して以下のコマンドを実行し、ingressを作成します

```shell:ingressを作成
kubectl apply -f ingress.yml
```

### 3-4. DNSの設定
ingressに割り当てられたIPアドレスを確認した後DNSのレコード設定を行い、 `https://[ドメイン名]` でWebブラウザからWebアプリケーションにアクセスして以下のようなページが表示されることを確認します
※ingressが正常に動作するまで時間がかかる場合があります
![14.png](https://qiita-image-store.s3.amazonaws.com/0/315248/f24f283c-fb64-f006-9eda-f117d741cff3.png)

## 4. IAPの有効化
画面左上のハンバーガーメニューをクリックし、 `IAMと管理` → `Identity-Aware Proxy` を選択します
![07.png](https://qiita-image-store.s3.amazonaws.com/0/315248/208332e1-2d45-02e8-ab33-1df3574aa6b7.png)
`同意画面を構成` をクリックし、OAuth同意画面を作成します
![08.png](https://qiita-image-store.s3.amazonaws.com/0/315248/5b67037b-22ca-8582-5e63-8aa2a306ab65.png)

### 4-1. OAuth同意画面の作成
適当な名前を入力した後、 所有しているドメイン名を`承認済みドメイン` に入力してEnterを押下し保存をクリックします
![09.png](https://qiita-image-store.s3.amazonaws.com/0/315248/d9bbb5b0-980a-a3c8-db1d-e2e45ae6d539.png)

### 4-2. IAPの有効化
再び `Identity-Aware Proxy` の画面を表示させた後、3-3.で作成したingressのIAPスイッチボタンをクリックします
![10.png](https://qiita-image-store.s3.amazonaws.com/0/315248/df725488-f5e5-16d4-c406-d22af5802e6f.png)
確認事項にチェックを入れ、 `有効にする` をクリックします
![11.png](https://qiita-image-store.s3.amazonaws.com/0/315248/2449e40a-c358-3bd9-075d-f9af2a091ff5.png)

## 5. OAuth承認済みのリダイレクトURIの設定
同項目の右側に表示されるメニューから `OAuthクライアントを編集` をクリックします
![12.png](https://qiita-image-store.s3.amazonaws.com/0/315248/ea1185d2-b7d6-60b7-60ae-eda6f9d5f5d1.png)
`承認済みのリダイレクトURI` に、以下のようなURI入力し、Enterを押下して保存をクリックします

```
https://[ドメイン名]/_gcp_gatekeeper/authenticate 
```

![13.png](https://qiita-image-store.s3.amazonaws.com/0/315248/1a5ff653-e125-cd9f-ec4d-502f7ee344c4.png)
※上記画面はIAPを有効化して少し時間が経たないと表示されない場合があります

## 6. 認証ページの確認
3-4.でアクセスしたURLにもう一度アクセスし、Googleの認証ページが表示されることを確認します
![15.png](https://qiita-image-store.s3.amazonaws.com/0/315248/c62a7a1a-55a6-77c1-1d30-04eb65234819.png)
また、適当なアカウントでログインしても3-4.で表示されたページが表示されないことを確認します
![16.png](https://qiita-image-store.s3.amazonaws.com/0/315248/a097baac-2c59-75c8-a257-fc799d9f1716.png)

## 7. アクセス許可ユーザの登録
再び `Identity-Aware Proxy` の画面を表示させた後、3-3.で作成したingressの項目の左側にチェックを入れます。右側に表示される情報パネル(表示されない場合は画面右上の `情報パネルを表示` をクリック)の `メンバーを追加` をクリックします
![18.png](https://qiita-image-store.s3.amazonaws.com/0/315248/8d2bb4a6-0039-b004-a951-917068c25f99.png)
Webアプリケーションへのアクセスを許可したいユーザのGoogleアカウント名を `新しいメンバー` に入力し、 `役割` として `Cloud IAP` → `IAP-secured Web App User` を選択して保存をクリックします
![17.png](https://qiita-image-store.s3.amazonaws.com/0/315248/2ac0622f-95b2-fe7b-f5ef-4bb2ceb2b9c4.png)

## 8. 認証ページの確認
6.でアクセスしたページにもう一度アクセスして7.で登録したユーザでログインします。その後Webアプリケーションのページが表示されればOKです

# 参考
* https://cloud.google.com/iap/docs/concepts-overview#how_iap_works
* https://cloud.google.com/iap/docs/enabling-kubernetes-howto
* https://www.kwbtblog.com/entry/2019/01/03/112619