Overview
oauth2-proxyはただのproxyなのでどんなサービスの前にもおくことができます。[*1] サイトのソースを一切いじらずに OIDC 認証をかけられる便利なやつです。
oauth2-proxyはTLS termination必須なので、前段のreverse proxyでTLS offloadするか、oauth2-proxyに証明書を渡してTLS terminationする必要があります。
実装例
この例ではdocker で2つのコンテナを起動しています。oauth2-proxyとweb serviceです。OIDCは外部にある前提です。前段のreverse proxyでTLS terminationされており、oauth2-proxy コンテナには http 通信が来ている想定です。
github
version: '3.8'
services:
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:latest
ports:
- "4180:4180"
command:
- --provider=keycloak-oidc
- --oidc-issuer-url=https://keycloak.example.com/realms/master
- --client-id=my-client
- --client-secret=${CLIENT_SECRET}
- --cookie-secret=${COOKIE_SECRET}
- --redirect-url=https://service.example.com/oauth2/callback
- --upstream=http://nginx:80
- --email-domain=*
- --errors-to-info-log
nginx:
image: nginx:latest
CLIENT_SECRET=keycloakから発行する
COOKIE_SECRET=任意の 32 文字
Note: upstream server(実際にweb serviceが稼働してるendpoint) は docker networkで oauth2-proxy container -> nginx へのルーティングがされているのでこういう書き方になってます。 (docker-composeのサービス名で名前解決できる) 実際の利用では外部のドメインなどになることでしょう
- --upstream=http://nginx:80
oauth2-proxy + keycloak の罠
Keycloak は Audience を追加しなければいけない
1つ大きな引っ掛けがありました。こんなエラーが出ました
oauth2-proxy-oauth2-proxy-1 | [2024/10/11 09:11:38] [oauthproxy.go:902] Error creating session during OAuth2 callback: audience from claim aud with value [...] does not match with any of allowed audiences map[:{}]
これは keycloak が default で access tokenの aud
に client-id を入れないのが原因らしいです。それが入ってるのが一般的だと chatGPT はいう。そうなんだ。
keycloak管理画面の
Client scopes > {client_id}-dedicated > Add mapper > By configuration > audience
これで一つ audience を作ります。Name
は任意ですが Included Client Audience
または Included Custom Audience
に oauth2-proxy に渡している --client-id
と同じ文字列が入る必要があります。ymlの例だと my-client
が入るべきです。
これで、無事 service.example.com にアクセスすると keycloak 認証を求められ、認証成功すると web serviceが表示されるようになりました。認証session は cookie 保存されるので reload するとストレートにweb serviceが見えます。便利。
ちなみに login後の cookie には _oauth2_proxy_0
_oauth2_proxy_1
という値がありました。local storage, session storage は空でした。
終わり!! 簡単だったぜ!
*1 oauth2-proxy は /oauth2
というpathを利用するのでサービス側はこのpathを使わないほうがいいです
keycloak以外との連携
一般的なOIDCとの連携もできました
https://github.com/kujiy/oauth2-proxy-playground/tree/master