0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

keycloak + oauth2-proxy でWebアプリのSSO + ロール認証実装してみた

Posted at

この記事は

  • keycloakのレルムロールを用いて,oauth2-proxyをリバプロとして認証を行う方法
  • keycloakのIdPとしてGoogleのログインを行い,SSOを実現する方法
  • これらの仕組みをdocker-composeで実現する方法

についてまとめる.

あらすじ

前回の記事および,自作のWebアプリをdocker-composeで運用する記事に引き続いて,今回はこれらのアプリと認証基盤を実際に運用するための構築を行なっていく.

今回は,Webアプリにアクセスできるのは,Admin(筆者)が認めた人物のみに絞りたいため,keycloakのレルムロールを用いて,特定のロールが付与されているかをoauth2-proxyで検証し,ロールが付与されていれば,Webアプリにアクセスできるという制御ができるように,いろいろ設定していく.ちなみに,アクセスが認められない人はちゃんと403を受け取れるようにもする.

docker-composeの構築

Webアプリ側

まず,Webアプリ側のdocker-compose.yamlの内容を以下に示す.Webアプリ側の構築の記事で構築した分に加えて,今回は認証を行うためにoauth2-proxyを導入する.

ただし,今回oauth2-proxyは,nginxよりも前に位置するリバプロとして動作させる.そして,特定ロールを持つユーザーのみにアップストリームのWebアプリへのアクセスを許可するように設定する.

docker-compose.yaml
services:
  front:
    build:
      context: ./front
      dockerfile: Dockerfile
    working_dir: /node/FileUploader/front/dir-share
    command: npm run start
  back:
    build:
      context: ./back
      dockerfile: Dockerfile
    working_dir: /go/src/FileUploader/back
    volumes:
      - ./.tmp:/tmp/share
    command: bash -c "./main"
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    depends_on:
      - front
      - back
  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:v7.7.1
    command:
      - --provider=keycloak-oidc
      - --oidc-issuer-url=http://auth.syou551.dev/realms/auth
      - --client-id=fileUploader
      - --client-secret=${CLIENT_SECRET}
      - --cookie-secret=${COOKIE_SECRET}
      - --redirect-url=https://fileup.syou551.dev/oauth2/callback
      - --upstream=http://nginx:80
      - --email-domain=*
      - --http-address=0.0.0.0:4180
      - --errors-to-info-log
      - --cookie-secure=false
      - --reverse-proxy=true
      - --allowed-role=${ALLOWED}
      - --whitelist-domain=auth.syou551.dev
    ports:
      - "8080:4180"
    depends_on:
      - nginx

oauth2-proxyは,keycloakのOIDCをサポートしているため,commandで--provider=keycloak-oidcを指定すれば良い.そのほかは,適宜OIDCの設定項目を指定していく.また,今回はリバプロとして動作させる必要があるので,--reverse-proxy=trueを指定するのを忘れないようにする.

そして,肝心の特定ロールのみ通過させるには--allowed-role=<許可するロール>を指定する.

--upstreamに関しては,同じdocker-compose内で動作させるため,サービス名で名前解決ができる.一方で,--oidc-issure-url--redirect-urlに関しては,クライアントが実際にリクエストするために使う値であるため,ドメインなどを指定するようにする.

keycloak側

これらのファイルに関しては,前回の記事で説明しているため,詳細は省略する.起動時に自動でSSLなしで外部からアクセスできるようにするため,元のENTRYPOINTとは別のshファイルを指定している.

keycloak/Dockerfile
FROM quay.io/keycloak/keycloak:latest

WORKDIR /opt/keycloak/bin
COPY ./setup.sh .

ENTRYPOINT ["/opt/keycloak/bin/setup.sh"]
docker-compose-yaml
version: "3"
services:
  keycloak:
    build: 
      context: ./keycloak
      dockerfile: Dockerfile
    tty: true
    stdin_open: true
    environment:
      DB_VENDOR: POSTGRES
      DB_ADDR: postgres
      DB_DATABASE: ${POSTGRES_DB_NAME}
      DB_USER: ${POSTGRES_USER}
      DB_PASSWORD: ${POSTGRES_PASSWORD}
      KEYCLOAK_ADMIN: ${KC_ADMIN_NAME}
      KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
      TZ: "Asia/Tokyo"
    ports:
      - "8010:8080"
    depends_on:
      - postgres
    volumes:
      - ./keycloak/.data:/opt/keycloak/data

  postgres:
    image: postgres:latest
    environment:
      POSTGRES_DB: ${POSTGRES_DB_NAME}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    ports:
      - "5432:5432"
    volumes:
      - ./postgres/.data:/var/lib/postgresql/data

これら2つのdocker-composeをそれぞれ起動させ,それぞれに対して外部からアクセスできるようにする.今回は,cloudflare tuunelを用いて公開した.(docker-compose.yamlに記されているURLはこれである)

Keycloakの設定

次に,KeycloakのWebUIを用いて設定を行っていく.

まず,公開したkeycloakサービスのURLにアクセスすると,masterレルムのログイン画面にリダイレクトされるはずなので,そこにyamlで指定したadminのユーザーネームとパスワードを入力し,ログインする.

image.png

レルムの追加

次に,認証用に新たなレルムを作成する.左上のコンボボックスをクリックし,出てくるCreate realmを押すと作成できる.(今回は新たなレルムであるauthを作成済み)

image.png

Clientの作成

そして,新たに作成したレルムのClientsページ(上記の写真のページ)で,Create Clientをクリックし,Webアプリ用のクライアントを作成する.

まず,表示される最初のページでは,今回はOIDCを用いるので,OpenID Connectを選択し,Client IDに任意の値を設定する.このIDが,oauth2-proxyの--client-idに設定する値となる.

image.png

次に,認証の詳細設定を行う.ここでは,初期設定では,Client authenticationがオフになっているので,オンにし,Authorizationもオンにする.そして,チェックを入れる項目は,選択固定されているものと,Standard flowのみで良い.
image.png

最後に,認可後にoauth2-proxyの方へリダイレクトするために,Valid redirect URIsを設定する.ここには,クライアント側のドメインまでを明示的に指定すればよく,パスに関してはワイルドカードを使用できる.(筆者の場合は,[https://fileup.syou551.dev/*]を設定している.)

なお,この設定は後でもできるため,URIが確定した時点で登録すれば良い,また,TailscaleなどのIPも入力することが可能だった.
image.png

Audienceの設定

次に,新たに作成されたClientにAudienceを追加する.これは,デフォルトでは設定されていないが,oauth2-proxyで認証を行うには必須の設定である.

参照:

Client Scopesの<clientid>-dedicatedをクリックし,Add Mapperをクリックする.
image.png
image.png

そして,By Configurationを選択し,表示されるリストの中からAudienceを選択する.
image.png

Audienceの設定では,Included Custom Audienceを設定する必要があり,この値はClient IDを指定する.Nameは設定必須だが,任意の名前を指定できる.

image.png

これらの設定が完了すれば,画面下部のSaveをクリックする.

IdPの設定

次に,GoogleをIdPとして使用するための設定を行う.最初に,左のConfigure欄のIdentity Providerの項目を選択する.初期状態ならば,様々なIdPの選択肢が表示されるが,その中からGoogleを選択する.すると,以下のような画面へ移動する.

image.png

Googleのconsoleでの設定は,詳しくは省略するが,事前にOAuthのクライアントIDを取得しておく.(以下のような画面で,クライアントが作成できていればOK)

そこで,クライアントIDとシークレットを控え,それをkeycloakのClient IDとClient Secretに入力する.Aliasがgoogleとしておけば良いだろう.また,Google側には,承認済みのリダイレクト URIとして,keycloakのRedirectURIに表示されているURIを設定しておく.

image.png

レルムロールの追加

次に,認証に用いるレルムロールを追加する.これは簡単で,Manage欄のRealm rolesを選択し,そこれCreate roleをクリックすると,以下のような画面へ飛ぶ.あとは,任意のロールの名前を設定すれば良い.ただし,oauth2-proxyのdocker-composeで指定したロールと同じロール名にすることを忘れないように.

image.png

oauth2-proxyへの設定

最後に,oauth2-proxyにClientとしてのデータを設定するための処理をする.先ほど作成した新たなClientを選択し,その中のCredentialsを選択する.そして,Client AuthenticatorとしてClient Id and Secretを選択すると,Client Secretが取得できるようになる.

image.png

ここで控えたSecretをdocker-compose.yamlの環境変数に設定するために,.envなどを用意して,そこに書き込んでおく.

.env
CLIENT_SECRET=<先ほど入手したkeycloakのやつ>

以上で,認証を行うための最低限の設定が完了した.

実際にユーザーにロールを割り当てるまで

これで,あとは特定のユーザーにロールを割り当てれば認証できるようになる.

まずは,実際にGoogleアカウントで認可を行い,keycloakにユーザーを作成する.新たに追加されたユーザーに対して,先ほど作成したレルムロールをAssignする.

ここでロールを追加するのは,自分のGoogleアカウントのメールアドレスを持ったユーザー,もしくは自分が確実にアクセスを許可したいユーザーである場合だけにすること

また,oauth2-proxyでは,EmailがVerifyされてないとInternal Server Errorとなってしまうので,手動でVerifyしておく.(確認メールを送信することもできるが,今回は設定していないので手動でやってしまう)

これで,特定ロールを持たないユーザーには403が返されるようになる.

まとめ

これで,無事にoauth2-proxyとkeycloakを用いて独自のロールを用いたSSOの仕組みを整えることができました!

Googleだけでなく,Github等のIdPも使用することができるみたい.便利〜

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?