LoginSignup
3
1

More than 1 year has passed since last update.

Keycloak を用いたリフレッシュトークンローテーション検証方法 メモ

Posted at
  • リフレッシュトークンローテーション機能をKeycloakを使って試してみたのでメモしておく。

リフレッシュトークンとは

  • アクセストークンの有効期限が切れた際に新しいアクセストークンを要求するために使用するトークン。
  • ネイティブアプリで使用されることが多い。

リフレッシュトークンローテーションとは

  • リフレッシュトークンを用いてアクセストークンを再発行する際に新しくリフレッシュトークンも再発行し、以前のリフレッシュトークンを無効化する機能。

    RT.png

Keycloakでの検証

設定

  • 「Realm Settings」->「Tokens」を選択
  • 「Revoke Refresh Token」を「ON」に設定
  • 「SSO Session Idle」を30に設定※デフォルトの1のままだと「token is not active」になったため。

動作確認

  1. リフレッシュトークン発行※認可コードグラントなどでリフレッシュトークンを発行する。

  2. 1で発行したリフレッシュトークンを使用してトークン再発行

    リクエスト

    POST /auth/realms/master/protocol/openid-connect/token HTTP/1.1
    Host: localhost:8080
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 784
    
    client_id=python-client&client_secret=a07...213d1&refresh_token=eyJhb...DZag&grant_type=refresh_token
    

    レスポンス

    {
        "access_token": "eyJhbGci...8eKzMz_kJ8yyvyQ",
        "expires_in": 60,
        "refresh_expires_in": 225,
        "refresh_token": "eyJhb...lOToY",
        "token_type": "Bearer",
        "id_token": "eyJhbGciOiJSUzI1NiI..._hWf40po2oMf7w",
        "not-before-policy": 0,
        "session_state": "db0815aa-3ac9-429c-9f59-f789bbe1953b",
        "scope": "openid profile email"
    }
    
  3. 1世代前のリフレッシュトークン無効化確認

    リクエスト※2のリクエストで指定したリフレッシュトークンを指定

    POST /auth/realms/master/protocol/openid-connect/token HTTP/1.1
    Host: localhost:8080
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 784
    
    client_id=python-client&client_secret=a07...213d1&refresh_token=eyJhb...DZag&grant_type=refresh_token
    

    レスポンス

    {
        "error": "invalid_grant",
        "error_description": "Token is not active"
    }
    

    ※2のリクエストで指定したリフレッシュトークンが無効化されていることがわかる。

  4. 新規発行リフレッシュトークンの有効性確認

    リクエスト※新規発行されたリフレッシュトークンを使用する。

    POST /auth/realms/master/protocol/openid-connect/token HTTP/1.1
    Host: localhost:8080
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 784
    
    client_id=python-client&client_secret=a07...213d1&refresh_token=eyJhb...lOToY&grant_type=refresh_token
    

    レスポンス

    {
        "access_token": "eyJhbGciOiJS....30BE04DYQ",
        "expires_in": 60,
        "refresh_expires_in": 497,
        "refresh_token": "eyJhbGciO...28ZoQyPY",
        "token_type": "Bearer",
        "id_token": "eyJhbGciOiJSUzI1NiIsIn...hdQ",
        "not-before-policy": 0,
        "session_state": "cd77a6ba-eda2-4ecc-a0bb-7248cd9695fa",
        "scope": "openid profile email"
    }
    

Keycloakリフレッシュトークン構造

  • ヘッダー部

    {
      "alg": "HS256",
      "typ": "JWT",
      "kid": "5361b8f...9ac2eb"
    }
    
  • ペイロード部

    {
      "exp": 1648350302,
      "iat": 1648350077,
      "jti": "09265c39...c6181bb52",
      "iss": "http://localhost:8080/auth/realms/master",
      "aud": "http://localhost:8080/auth/realms/master",
      "sub": "dc6f27d...dd61e64cd",
      "typ": "Refresh",
      "azp": "python-client",
      "session_state": "db0815...be1953b",
      "scope": "openid profile email",
      "sid": "db0815...e1953b"
    }
    
3
1
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
3
1