OAuth2 Proxyで外部認証(2) Keycloak編


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/d19de6af-c6d0-d0d5-1717-707851eb976f.png)

# 概要

- 自前の認証機能を持っていない、既存のウェブサイトや独自アプリがある
- Basic認証などで都度ID/パスワード設定するのは古臭いし管理たいへんなので止めたい
- シングルサインオンできる __自前の認証機能__ を使いたい


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/cfc21c1d-26ba-525e-8083-d10be7308aa0.png)


# はじめに

この記事は以下の続編です。

- [OAuth2 Proxyで外部認証(1) GitHub編](/k2ok/items/da98f326c26a03da7b7f)
- [Keycloakによる認証基盤の立ち上げ(1) Wildfly版](/k2ok/items/dbf41ac8a7e3cd873bbb)

1. OAuth2で「外部の」認証基盤を利用する仕組みは出来た。
1. Keycloakで「自前の」認証基盤立ち上げは出来た。

なので、（満を持して）自前の認証基盤でSSOできる仕組みへ移行。


# 設定の流れ

## OAuth2 Proxyのドキュメント確認

ドキュメントの [Keycloak OIDC Auth Provider](https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/keycloak_oidc) の項を見ておく。
この項と別に [Keycloak Auth Provider](https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/keycloak) という項もあるが、冒頭のnoteに「こっちは古いやつ」って書いてあった。


## Keycloakの設定

1. Realmの追加（任意）
1. クライアントの作成
1. secretを控える
1. mapperの作成（2個）

### Realmの追加

Realmは、まだ運用シナリオも決まってないので、とりあえず今回用に新規作成した。
「クライアント」を複数作成できるようなので、そもそもそんなに分離する必要もないのかもしれない。

### クライアントの作成

Clientsタブに移動し、右上の「Create」ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/bc2da7f2-f0cb-7f74-5cf1-76d241ce624e.png)

任意のClient IDを入力して追加。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/26f64c9b-0398-a3e6-323e-8bf56950a5d5.png)

OAuth2 Proxyのドキュメントには「Access Type 'confidental'」で作成しろって書かれているけど、作成画面には無い。。
と思ったら、作成後の設定画面にあった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/f8d07be0-541d-d2ac-7f56-6c0bc6f4651a.png)

「Valid Redirect URL」には、Github版で指定したのと同じリダイレクト先を指定。
（OAuth2 Proxy側で設定済み）

[https://example.com/oauth2/callback](https://example.com/oauth2/callback)


### secretを控える

Credentialsタブに移動し、記載されているsecretを `oauth2-proxy.cfg` に転記する。


### mapperの追加

Mappersタブに移動し「Create」ボタンを押す。
Mapper Typeとして、以下の2つを作成しろとある。
1. Group Membership : Token Claim Name = 'groups' とする
1. Audience : `Included Client Audience` と `Included Custom Audience` に、作成したクライアント名を追加する


ここまで、わけもわからずドキュメントの指示に従って作業しただけ。


```
http_address = "127.0.0.1:3333"
reverse_proxy = true
redirect_url = "https://example.com/oauth2/callback"
upstreams = [
    "http://inside.example.com/"
]
header = true
pass_host_email_domains = [
    "your-mail.example.com"
]
provider = "keycloak-oidc" ★
client_id = "oaproxy-app" ★
client_secret = "xxxx" (Credentialsタブからの転記) ★
oidc_issuer_url = "https://keycloak.example.com/auth/realms/practice1800" ★
cookie_secret = "xxxx"
```

★をつけたところが、Github版から変更された行


## 認証設定の確認

oauth2-proxyコマンドを再起動。

InPrivateウィンドウを開いて、未認証状態から認証開始してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/20addf95-5bee-3160-de64-38f4cf8a1c9d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/a863fd89-8d72-35d7-2686-4dd5851ba427.png)

あれれ...？？

あっ、そうかこれ、master Realm（Keycloakの管理用Realm）とは別に作成したので、同じユーザーで入れないということか。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/53bc9fa4-9f42-5f88-05ce-7b0f1e9096d4.png)

とりあえず別名でアカウント追加してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/3976806e-b6f4-6ea0-4286-88ee8c0a9efe.png)

パスワードを設定。Temporaryはオフに。

このアカウントの他の設定:

- `your-mail.example.com` ドメイン配下のEmailアドレスを登録（pass_host_email_domainsへの対応）
- `Email Verified` 項のスイッチを「ON」にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50759/b7ffa729-418b-9015-195d-cb75ffa41f7c.png)

設定したユーザIDとパスワードでログインすると、アプリへのログインができた。

ヘッダに落ちてくる情報がだいぶ変わった。

```/apps/env.cgi
HTTP_X_FORWARDED_EMAIL => 'k2ok@your-mail.example.com',
HTTP_X_FORWARDED_FOR => '127.0.0.1',
HTTP_X_FORWARDED_GROUPS => 'role:offline_access,role:default-roles-practice1800,role:uma_authorization,role:account:manage-account,role:account:manage-account-links,role:account:view-profile',
HTTP_X_FORWARDED_HOST => 'example.com',
HTTP_X_FORWARDED_PREFERRED_USERNAME => 'k2ok-app',
HTTP_X_FORWARDED_USER => '161d332a-9f29-4da0-a004-471465e6535d',
```

`HTTP_X_FORWARDED_USER` が、アカウント名ではなくuuidらしき文字列になっている。
同じアカウント名であっても、過去のユーザーとは紐づかないということか。。

Realmに関する情報がヘッダに含まれていないが、 `oidc_issuer_url` で認証の依存先は明示しているので、
他の認証プロバイダとのフェデレーションが出来るということは、おそらく同じKeycloakベースの異なるRealm間のフェデレーションも出来るんじゃないかと思われるが、どこまで同じユーザーが一意に定まるのかは調査が必要そう。


## 今回の設定から足りていないと思われるところ

とりあえず管理画面強制で逃げてしまったが、KeycloakのEmail Validationを促すためのURLパラメータがOAuth2 Proxy側にあるんじゃないだろうか。
また、Keycloak側では新規ユーザの登録を受け入れる仕組みがあって、Realmで受付許可設定ができるので、これに対応するURLの指定もOAuth2 Proxy側にあると思われる。


# 感想

Keycloakはきめ細かい権限分離がいろいろ出来るようだが、全容を押さえるのはかなり難儀しそうに感じた。

この認証基盤を活かせるほどの大量のミニアプリが存在する会社というのは、どれくらいあるんだろうか。。