mikakimikaki.org

mikakiのOpenID Connectアプリ連携

公開IdPへの接続をブラウザーで試す方は、公開接続デモへ進めます。 このガイドは、秘密鍵をバックエンドに保管するWebアプリをmikakiへ接続する開発者向けです。管理者への登録依頼、ログインの開始、コード交換、アプリのセッション作成までを説明します。利用者のログイン手順ははじめ方を参照してください。

OpenID Connectで接続する#

mikakiはOpenID Connect Provider(OP)として動作します。連携先アプリはRelying Party(RP)として、Authorization CodeフローとPKCE S256を使ってログインを開始します。

Discovery URLは次のとおりです。

https://auth.mikaki.org/.well-known/openid-configuration

エンドポイントや公開署名鍵のURLはDiscoveryから取得します。通常の連携では、openidスコープとES256のprivate_key_jwtによるクライアント認証を使います。クライアント登録は管理者による事前登録です。

登録に必要な情報#

環境ごとに別のクライアントを用意し、アプリ名、ホスト名、正確なHTTPSコールバックURL、ES256用の公開JWKとその鍵IDを管理者へ提供します。秘密鍵はアプリのバックエンドに保管し、mikakiへ送らないでください。公開の動的クライアント登録APIはありません。

ネイティブの公開クライアントには別の登録・認証・コールバックのルールがあります。

登録を依頼する前に、アプリ連携の相談で必要な情報と確認の流れをまとめられます。

1. ログインを開始する#

ログインごとにランダムなstate、nonce、PKCEのcode_verifierを生成し、開始時刻とブラウザのトランザクションに結び付けてバックエンドへ保存します。ログイン後の戻り先はアプリ内の検証済みパスに制限してください。

Discoveryのauthorization_endpointへ、次の値をURLエンコードして送ります。

パラメーター値
client_id登録されたクライアントID
redirect_uri登録と完全一致するコールバックURL
response_type / scopecode / openid
state / nonceこのログイン用に生成した値
code_challengeverifierのSHA-256を、末尾の=なしのbase64urlで表した値
code_challenge_methodS256

利用者のパスキー認証と接続承認はmikakiの画面で行います。アプリがパスキーやmikakiのSSO Cookieを受け取る手順はありません。

2. コールバックでコードを交換する#

保存したトランザクションとstateを照合し、応答のissがhttps://auth.mikaki.orgと完全一致することを確認します。エラー応答、期限切れ、処理済みのトランザクションではセッションを作成しません。コードをアクセスログへ記録しないでください。

バックエンドからDiscoveryのtoken_endpointへ、application/x-www-form-urlencodedでPOSTします。grant_type=authorization_code、受け取ったcode、登録したredirect_uri、保存したcode_verifier、client_id、client_assertion、client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearerを送ります。

クライアントアサーションは、登録した秘密鍵で署名するES256のJWTです。ヘッダーのkidは登録した公開鍵に対応させます。issとsubはクライアントID、audはDiscoveryから取得したトークンエンドポイントの正確なURLです。要求ごとに新しいjtiと、運用設定の有効期間に収まるiat・expを使います。応答が失われてもコードやJWTを再送せず、新しいログインからやり直してください。

ID TokenはJWKSと許可した署名アルゴリズムで検証し、発行者、対象クライアント、有効期限、発行時刻、送信したnonce、必要なauth_timeを確認します。アプリのユーザーには、発行者とsubの組を対応付けます。subはメールアドレスやmikaki共通のアカウントIDではありません。

Access TokenはUserInfo取得用であり、アプリ自身のAPI認可やセッションの有効性確認には使いません。UserInfoを取得する場合は、そのsubが検証済みID Tokenと一致することを確認します。

3. アプリのセッションを作成する#

管理対象RPはCookieを発行する前に、バックエンドからPOST https://auth.mikaki.org/session/checkを呼びます。これはmikaki固有の拡張です。JSONでclient_id、client_assertion_type、新しいclient_assertion、ID Tokenのsidを送ります。

JWTの用途audに指定するURL
コード交換Discoveryのtoken_endpoint
セッション確認https://auth.mikaki.org/session/check

セッション確認用には新しいJWTとjtiが必要です。トークン交換用のアサーションを再利用できません。active=trueならsubとauth_timeをID Tokenと照合し、確認開始時点から測ったlease_ttlと親SSOのexpires_atを越えない確認期限を設定します。固定の確認間隔を仮定せず、応答の値を使ってください。

アプリのセッション期限は、応答のapp_idle_timeoutから定まるアイドル期限と親SSOの有効期限のうち早い方に制限します。失効したセッションを、遅れて届いた有効応答で復活させないでください。

アプリ自身のホスト専用CookieをSecure・HttpOnly・SameSite=Laxで発行します。mikakiとCookieのDomainを共有しません。確認期限を過ぎた保護リクエストでは状態を再確認し、OP停止時に期限を延長しないでください。最初の確認に失敗した場合は、新しいセッションを作成できません。

ログアウトを接続する#

ログアウト後の戻り先とBack-Channel Logoutの受信先は別々に登録します。受け取った署名付きログアウト通知を検証し、対応するアプリのセッションを失効させます。通知が届かない場合も、セッション確認の期限を越えて保護操作を続けないことを検証してください。

接続できないときの確認順序#

  1. 発行者・クライアントID・コールバックURLが同じ環境の登録と一致するか確認します。URLのパス、末尾のスラッシュ、クエリも区別されます。
  2. コールバックが同じブラウザの未処理トランザクションに対応しているか確認します。stateやnonceを固定値にして動作確認しないでください。
  3. コード交換ではPKCEの保存値、鍵のkid、JWTのaud、時刻と有効期間を確認します。秘密鍵、コード、トークンを診断ログや公開Issueへ貼らないでください。
  4. セッション確認では新しいJWTを使っているか、そのsidが同じクライアントに発行されたものかを確認します。active=falseを成功扱いにせず、ログインからやり直します。

現在の対応範囲#

本番連携の基本スコープはopenidです。名前の属性提供には別の同意・運用設定・検証が必要で、通常のログインだけでVaultの名前やノートを受け取れるわけではありません。emailスコープ、動的登録、一般的なFAPI対応を提供していると仮定しないでください。

登録完了だけでは動作確認になりません。コード交換に加え、不正なstate・nonce・PKCE・署名、再送、失効、ログアウト、OP停止時の挙動をそのアプリから検証してください。正式認定とローカルのテスト結果は対応状況に分けて掲載しています。

標準の手順はOpenID Connect CoreとPKCE仕様を参照してください。mikakiの設定と検証の詳細はRP連携ガイド、クライアント登録手順、セッション確認の契約を参照してください。

次に読む#