16
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ミライトデザインAdvent Calendar 2021

Day 2

Keycloak で Opent ID Connect 認可コードフローをやってみる

Last updated at Posted at 2021-12-02

ミライトデザインアドベントカレンダー2日目です。
ミライトデザイン Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita

1日目は ほげさん でした。
自分も IntelliJ をずっと使っていますが背景画像が設定できるのは知りませんでした。ありがとうございました。

2日目は最近触っている Keycloak で OIDC の認可コードフローを試してみたいと思います。

この記事でやること

Keycloak で OIDC の認可コードフローを試してみます。

Laravel のコードが実際どんなことをしているのかにも触れていこうと思います。

OIDC の内容については触れていません。その代わりに自分が OIDC を勉強する際に参考にさせてもらった参考書や記事を貼っておきます。

OpenID Connect入門: 概念からセキュリティまで体系的に押さえる | 土岐 孝平 | Kindle本 | Kindleストア | Amazon

雰囲気で使わずきちんと理解する!整理してOAuth2.0を使うためのチュートリアルガイド (技術の泉シリーズ(NextPublishing)) | Auth屋 | 工学 | Kindleストア | Amazon

実際に動かしてみたい人は

環境構築

  1. github からコードを pull してくる
    GitHub - kakiuchi-miraito/keycloak-oidc
  2. make up
  3. http://localhost:8082/auth/

Keycloak の画面が表示されていれば ok です。

FD088083-E55C-40E9-9F2F-12E39CED4456.png

次に Keycloak の管理画面から認証を行うユーザーと、クライアント(今回だとLaravel)を追加します。

  • Administration Console にアクセス
    • id / password : admin / admin

クライアントを追加

  • Clients > Create

D9A5102B-1552-45AD-A9E4-50D67A3C8719.png

92A1E0DF-50F3-450D-B8FF-B8FE2772EE80.png

  • Consent Required

    • 同意画面を表示する設定
  • Access Type を confidential へ変更

  • Valid Redirect URIs に http://localhost*を入力

スクリーンショット 2021-11-16 2.23.11.png

  • Credentials の Secret をコピー(後で使う)

98D042A2-89AC-4399-A20B-F9E0AEFC33E9.png

User を追加

  • Users > Add user

BAEBF410-1EC7-48A2-A17A-A2781C0992E9.png

  • Username を入力(なんでも ok)

3DF547F9-546C-4AC0-9AEB-3D6C4AC76092.png

  • Credentials から Password を設定
    • Temporary は off
      • ユーザーがログイン後にパスワードを変更する必要があるかどうかの設定。今回はどうでもいいので off

EA5849DD-F3BF-4738-8B39-0BA35B0311C5.png

認可コードフローを試してみる

OIDC - 基本的なシーケンス図.png

認可コードフローで ID token を取得

  • backend/app/Http/Controllers/TokenRequest.phpclient_idclient_secret を作成したクライアントの値に修正
  • http://localhost/getAuthorizationCode へアクセス
    • Keycloak のログイン画面が表示される

2B3DFA46-FEF3-4719-82D7-1716F3929960.png

  • 同意画面が表示される
    • ちなみに同意したら履歴が残って次回から同意画面が表示されくなる
    • Users > Consents から履歴を削除できる

9BBCCFDD-B332-4AF2-AE2D-0E2C73034215.png

  • ログインすると ID Token が取得できる

image.png

B1915FCE-5ABA-4039-9986-FD9AC5BB11BC.png

  • 管理画面で user の email を追加すると ID Token にも Email の情報が反映される

22CABFB5-5B72-42C3-92F6-E98D0D078E34.png

コード解説

認可コードを取得

backend/app/Http/Controllers/GetAuthorizationCode.php

header(
    'Location: <http://localhost:8082/auth/realms/master/protocol/openid-connect/auth?'> .
    'response_type=code&' .
    'client_id=test-client&' .
    'redirect_uri=' . urlencode('<http://localhost/tokenRequest>') . '&' .
    'code_challenge=' . $codeChallenge . '&' .
    'code_challenge_method=S256&' .
    'scope=openid'
);

  • Location
    • 認可エンドポイント
  • response_type
    • 認可エンドポイントは必須のパラメーターとして response_type を要求
    • code token id_token noneが指定可能
    • scope との組み合わせでフローが決まる
    • OpenID Connect 全フロー解説 - Qiita
  • client_id
    • 作成したクライアントの ID を指定
  • redirect_uri
    • 認証完了後に認可コードをつけてリダイレクトされる uri
  • scope

PKCE について

Auth0を利用してOAuth 2.0のPKCEを理解する | DevelopersIO

PKCEは認可コードの横取り攻撃の対策として定義されています。

image.png

関連するのは
code_challenge_method code_challenge code_verifier

code_verifier はトークンリクエストの時出てきます。

  • code_challenge_method に記載されている方法でcode_verifier を変換することで、code_challenge を作成します
  • code_challenge_method code_challenge を認可リクエストの際に認可サーバーへ送信し、認可サーバー側で保存
  • アクセストークンリクエストの時にcode_verifier を送信し、認可サーバー側でcode_verifier からcode_challenge生成し、保存したcode_challengeと比較することで、第3者から認可コードが送信されていないことを確認します。
    • code_challenge_method がとりえる値は plain or S256
      • Plain は変換しないので、code_challenge = code_verifier になり、セキュリティ的に脆弱
      • S256はSHA256ハッシュ化したものをbase64URLエンコード化する手法
        • S256 にを選択するべき

アクセストークンリクエスト

backend/app/Http/Controllers/TokenRequest.php

$client = new Client();
$method = 'POST';
$uri = '<http://keycloak:8080/auth/realms/master/protocol/openid-connect/token>';
$options = [
    'client_id' => 'test-client',
    'client_secret' => '88a69be6-eac6-4d0e-bbd5-dfd9023a8acd',
    'grant_type' => 'authorization_code',
    'code' => $_GET['code'],
    'scope' => 'openid',
    'redirect_uri' => '<http://localhost/tokenRequest>',
    'code_verifier' => $codeVerifier,
];

$response = $client->request($method, $uri, ['form_params' => $options]);

リダイレクト URL に http://localhost/tokenRequest を指定しているので、このファイルに認可コードをもった状態でリダイレクトされてきます。

認可コードをトークンエンドポイントへ送信することで、ID Token を取得しています。

今回は出てこなかった Resource Server について

終わり

次回の記事は @Nyokki さんが MySQL 関連の記事を上げてくれるそうです。
@Nyokki さんがミライト社内で MySQL の勉強会をしてくれた時はわかりやすくてかなり勉強になりました。その節はありがとうございました。🙏

16
9
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
16
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?