LoginSignup
9
4

More than 1 year has passed since last update.

curlとKeycloakではじめるOpenID Connect

Last updated at Posted at 2022-12-14

この記事はラクスアドベントカレンダーの15日目の記事です。昨年から1年ぶりの投稿です。

今年は業務で、OpenID ConnectやOAuthやSAMLなど認証・認可プロトコルに触れることが多かったです。
OpenID Connectの勉強をする際に、Relaying Partyを用意するのが面倒なのと、実際のフローを確認したかったので、curlとKeycloak利用してOpenID Connectで認証してみました。

OpenID Connectの仕様書は理解したけど、実際の認証フローの想像がつかない方はぜひ参考にしてみてください。

環境

Keycloakは19.0.2を利用し、ローカルのDockerでlocalhost:8080で動作しています。

curlとKeycloakでAuthorization Code Flow

Keycloakの準備

Keycloakには、oidc-sampleというRealmに、rp1というOpenID ConnectのClientと、adminというUserを作成しています。
Clientの主に変更・取得した設定は以下になります。

設定
Client ID rp1
Valid redirect URIs http://localhost:3000/oidc
Client authentication On
Client secret Credentialsタブから取得

KeycloakのOpenID Connectプロバイダー情報はhttp://localhost:8080/realms/oidc-sample/.well-known/openid-configurationから取得できます。
今回は以下のエンドポイントを利用します。

エンドポイント名 エンドポイント
Authorization Endpoint http://localhost:8080/realms/oidc-sample/protocol/openid-connect/auth
Token Endpoint http://localhost:8080/realms/oidc-sample/protocol/openid-connect/token
UserInfo Endpoint http://localhost:8080/realms/oidc-sample/protocol/openid-connect/userinfo

Authorization Code Flow

詳しくは説明しませんが、以下のようなフローになります。

OpenID Connect Core 1.0 incorporating errata set 1から引用
  1. Authentication Request
    RP(今回はcurlを実行するPC)がOP(Keycloak)に認証リクエストを送る
  2. Authentication & Authorization
    OPはEnd-Userを認証、認可する
  3. Token Request
    OPはID TokenとAccess TokenをRPに発行する
  4. UserInfo Request $ Response
    RPはAccess Tokenを添えてUserInfo Endpointにリクエストを送り、OPはEnd-UserのClaimを返す

では早速Authentication Requestから実施します。

Authentication Request

IDトークンとアクセストークンを発行するために必要な認証コードを取得するために、Authentication Requestを発行し、Keycloakにログインします。
ブラウザでログインが必要なため、以下のURLにブラウザでアクセスします。

http://localhost:8080/realms/oidc-sample/protocol/openid-connect/auth?response_type=code&client_id=rp1&redirect_uri=http://localhost:3000/oidc&scope=openid

Keycloakのログイン画面が表示されます。

keycloak login

Authentication & Authorization

Keycloakのログイン画面が表示されるので、Userでログインします。ログインに成功すると、redirect_uriに設定したURLにリダイレクトされますが、localhost:3000でWebアプリを動かしていないのでエラー画面が出ます。

error

が、気にせずURLを取得してください。以下のようなURLを取得できると思います。

http://localhost:3000/oidc?session_state=・・・・&code=<認証コード>

codeパラメータが認証コードになります。ではこの認証コードを利用してIDトークンとアクセストークンを発行します。

Token Request

取得した認証コードを利用してToken Endpointで、IDトークンとアクセストークンを発行します。

curl -d "grant_type=authorization_code&code=<認証コード>&redirect_uri=http://localhost:3000/oidc&client_id=rp1&client_secret=<Client secret>" http://localhost:8080/realms/oidc-sample/protocol/openid-connect/token

Token Requestが成功すれば以下のようなToken Responseが返り、IDトークンとアクセストークンを取得できます。

{
  "access_token": <アクセストークン>,
  "expires_in": 300,
  "refresh_expires_in": 1800,
  "refresh_token": <リフレッシュトークン>,
  "token_type": "Bearer",
  "id_token": <IDトークン>,
  "not-before-policy": 0,
  "session_state": "8468db1c-feb4-4803-bfeb-213149b560cf",
  "scope": "openid email profile"
}

jwt.ioなどで各種トークンを確認してみてください。

UserInfo Request $ Response

取得したアクセストークンを利用して、UserInfo EndpointからKeycloakのUser情報を取得します。

curl -H "Authorization: Bearer <アクセストークン>" http://localhost:8080/realms/oidc-sample/protocol/openid-connect/userinfo

以下のようなUser情報を取得できると思います。

{
  "sub": <User ID>,
  "email_verified": false,
  "preferred_username": "admin",
  "given_name": "",
  "family_name": ""
}

もしアクセストークンの有効期限が切れている場合は、以下のようにリフレッシュトークンを利用して、アクセストークンを再発行してください。

curl -X POST -d "client_id=rp1&client_secret=<Client Secret>&grant_type=refresh_token&refresh_token=<リフレッシュトークン>&scope=openid profile" http://localhost:8080/realms/oidc-sample/protocol/openid-connect/token

以上、curlとKeycloakでAuthorization Code Flowを実践してみました。

終わりに

実際に手で動かすと、より理解が深まると思います。
OpenID Connectの仕様を理解するための手段の1つとして、ぜひ参考にしてみてください。

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