コンテンツにスキップ

OIDC@SSO

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. OIDC:OpenID Connect (外部ID連携)

OIDCとは

SSOの一種である。

OAuthをベースとして、認証フェーズを追加し、認証/認可を実装する。

そのため、OAuthの一種ともいえる。


02. OIDCの仕組み

アーキテクチャ

認証フェーズの委譲先のIDプロバイダー、ログインしたいWebサイト、から構成される。


クレーム

クレームは認証情報の要素である。

委譲元のクライアントは、IDプロバイダーから取得したクレームを認証情報として扱い、認可処理を実行する。

クレーム 説明
sub アカウントの識別子
profile アカウントのプロフィールURL
name アカウントの氏名
email アカウントのメールアドレス
phone アカウントの電話番号
address アカウントの住所
... ...


認可リクエスト時のクレームの取得

scopeパラメーター

認可リクエスト時に、scopeパラメーターでクレームグループを指定し、IDプロバイダーからクレームを取得できる。

IDプロバイダーは、取得したクレームグループに対応したクレームをIDトークンに設定し、クライアントに返信する。

委譲元のクライアントは、取得したクレームを認証情報として扱い、認可処理を実行する。

クレームグループ 取得できるクレーム (認証情報の要素)
openid これは、OIDCの場合に必須である。トークンエンドポイントから、アクセストークンに加えてIDトークンを発行できるようになる。
profile namefamily_namegiven_namemiddle_namenicknamepreferred_usernameprofilepicturewebsitegenderbirthdatezoneinfolocaleupdated_at
email emailemail_verified
phone address
address phone_numberphone_number_verified
ユーザー定義のクレームグループ 自由にクレームを設定できる

claimsパラメーター

認可リクエスト時に、claimsパラメーターで特定のクレームを指定し、クレームを取得できる。

クレームの指定の仕方が複雑らしい...


03. トークンの検証

IDトークン検証

アクセストークンの発行前に、IDトークンの有効期限や発行元認証局が正しいかどうかを検証する。


アクセストークン検証

発行後のアクセストークンが有効期限や発行元認証局が正しいかどうかを定期的に検証する。

以下のいずれかの方法で検証できる。

  • 認可サーバーのイントロスペクションエンドポイントにリクエストする
  • 認可サーバーから取得した公開鍵を使用して、アクセストークンの署名を検証する


04. OIDCの種類

ベースになっているOAuthと同様にして、OIDCには仕組み別に『認可コードフロー』『暗黙的フロー』『リソースオーナー・パスワード・クレデンシャルズフロー (ダイレクト・アクセス・グラント) 』などがある。


05. OAuthとの違い

トークンの違い

OIDCはOAuthの拡張であるため、仕組みは非常に似ている。

OIDCでは、OAuthとは異なり、アクセストークン (JWT仕様かどうかはツール次第) だけでなくIDトークン (必ずJWT仕様) の使用する。

また、OAuthの脆弱性に対処できる。

oidc_vs_oauth


06. 認可コードフロー

仕組み

OAuthの認可コードフローと仕組みが似ており、アクセストークンだけでなくIDトークンも使用する。

短命な認可コードを送信すると、IDプロバイダーからリフレッシュトークンを含むアクセストークンとIDトークンを取得できる。

oidc_codeflow


Keycloakの場合

▼ 認可リクエスト送信

アプリからKeycloakに宛に認可リクエストを送信する。

$ curl http://<Keycloakのドメイン>/realms/oidc-sample/protocol/openid-connect/auth?response_type=code&client_id=rp1&redirect_uri=http://<アプリのドメイン>/oidc&scope=openid

▼ 認可レスポンス受信

認可レスポンスを受信し、アプリに対してリダイレクトを送信する。

$ curl http://<アプリのドメイン>/oidc?session_state= ... &code=<認証コード>

▼ トークンリクエスト送信

認可コードを使用して、Keycloakにトークンリクエストを送信する。

IDトークンとアクセストークンを取得できる。

$ curl -d "grant_type=authorization_code&code=<認証コード>&redirect_uri=http://<アプリのドメイン>/oidc&client_id=rp1&client_secret=<Client secret>" http://<Keycloakのドメイン>/realms/oidc-sample/protocol/openid-connect/token

{
  "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"
}

▼ ユーザー情報の取得

$ curl -H "Authorization: Bearer <アクセストークン>" http://<Keycloakのドメイン>/realms/oidc-sample/protocol/openid-connect/userinfo

{
  "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://<Keycloakのドメイン>/realms/oidc-sample/protocol/openid-connect/token


運搬

アクセストークンをAuthorizationヘッダーで運べる。


07. SLO:シングルログアウト

シングルログアウトとは

SSOをログアウトする仕組みのこと。

複数の方式を組み合わせてSSOをログアウトする。


RP-Initiated

▼ シングル

▼ グローバル

記入中...


フロントチャネル

▼ シングル

▼ グローバル

フロントエンドのブラウザが、IDプロバイダーのログアウトエンドポイント (<IDプロバイダーのドメイン>/<IDプロバイダーによる>) にPOSTリクエストを送信し、全てのアプリケーションからログアウトする。


バックチャネル

▼ シングル

▼ グローバル

IDプロバイダーが、バックエンドのいずれかのアプリケーションのログアウトエンドポイント (<アプリケーションのドメイン>/<IDプロバイダーのクライアントパッケージによる>) にPOSTリクエストを送信し、そのアプリケーションでログアウト処理を実行する。

セッションデータが失効し、バックエンドのアプリケーションが起点となってログアウト処理を始める場合、それはバックチャネルである。

また、フロントエンドのブラウザがバックエンドのアプリケーションにログアウトリクエストを送信し、これが起点となる場合もバックチャネルである。