メインコンテンツまでスキップ
プレビュー版
PocketSign Link v2 は現在プレビュー版です。正式提供までに仕様が変更される可能性があります。

ネイティブアプリ向け OIDC 連携

既存のネイティブアプリ(iOS / Android)に PocketSign Link v2 の OIDC ログインを組み込む場合の構成です。 ネイティブアプリは OAuth 2.0 の Public Client として動作し、PAR + PKCE を組み合わせて安全な認可フローを実現します。

自社のネイティブアプリに PocketSign Link v2 を ID 基盤としたログイン機能を追加したい場合や、アプリ内の WebView で v2 連携済みの Web サービス(RP)を利用したい場合に参照してください。

準拠する仕様

PocketSign Link v2 のネイティブアプリ向け OIDC 連携は、以下の標準仕様をベースにしています。

ブラウザフローとの違い

観点ブラウザ(Confidential Client)ネイティブアプリ(Public Client)
クライアント認証client_secret または private_key_jwtなし(client_id のみ)
PKCE推奨必須S256
redirect_urihttps:// スキーム(サーバーサイド)アプリに戻る URI(Universal Links / App Links / カスタムスキーム)
トークン交換サーバーサイドアプリ内で直接実行

前提条件

  • PocketSign Platform で OIDC クライアントを Public Client として登録する
  • redirect_uri にアプリへのコールバック URI を登録する
  • client_secret は発行されない

フロー図

PAR(Pushed Authorization Request)

ネイティブアプリでは、認可パラメータを事前にサーバーに送信する PAR の利用を推奨します。

curl -X POST "https://id.mock.klon.you/api/oidc/v1/par" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=<CLIENT_ID>" \
-d "redirect_uri=https://app.example.com/callback" \
-d "response_type=code" \
-d "scope=openid" \
-d "state=<STATE>" \
-d "nonce=<NONCE>" \
-d "code_challenge=<CODE_CHALLENGE>" \
-d "code_challenge_method=S256"

レスポンスで request_uri が返されます。

アプリ内の WebView で v2 連携済みの Web サービスを表示し、セッションバインドも使う場合は、native スコープも要求してください。 このスコープを含むアクセストークンを POST /api/native/v1/bind で使用します。

curl -X POST "https://id.mock.klon.you/api/oidc/v1/par" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=<CLIENT_ID>" \
-d "redirect_uri=https://app.example.com/callback" \
-d "response_type=code" \
--data-urlencode "scope=openid native" \
-d "state=<STATE>" \
-d "nonce=<NONCE>" \
-d "code_challenge=<CODE_CHALLENGE>" \
-d "code_challenge_method=S256"

認可リクエスト

PAR で取得した request_uri を使ってシステムブラウザで認可エンドポイントを開きます。

https://id.mock.klon.you/api/oidc/v1/authorize?client_id=<CLIENT_ID>&request_uri=<REQUEST_URI>
備考

Public Client の場合、request_uri なしで直接パラメータを渡す方式も利用可能ですが、パラメータの露出を最小化するため PAR の利用を推奨します。

PKCE

Public Client では PKCE(Proof Key for Code Exchange)が必須です。

  1. ランダムな code_verifier(43〜128 文字の英数字 + -._~)を生成する
  2. code_challenge = BASE64URL(SHA256(code_verifier)) を計算する
  3. PAR または認可リクエストに code_challengecode_challenge_method=S256 を含める
  4. トークン交換時に code_verifier を送信する

トークン交換

認可コードを受け取ったら、アプリ内から直接トークンエンドポイントを呼び出します。

curl -X POST "https://id.mock.klon.you/api/oidc/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=<AUTHORIZATION_CODE>" \
-d "redirect_uri=https://app.example.com/callback" \
-d "client_id=<CLIENT_ID>" \
-d "code_verifier=<CODE_VERIFIER>"

Public Client ではクライアント認証が不要なため、client_id のみで呼び出します。

リフレッシュトークン

Public Client にもリフレッシュトークンが発行されます。

curl -X POST "https://id.mock.klon.you/api/oidc/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=<REFRESH_TOKEN>" \
-d "client_id=<CLIENT_ID>"

実装上の要件とプラクティス

システムブラウザを使用する

認可リクエストは、アプリ内の WebView ではなく システムブラウザASWebAuthenticationSession(iOS)や Chrome Custom Tabs(Android))を使って開いてください。

RFC 8252 では、ネイティブアプリが認可リクエストをシステムブラウザ経由で行うことを求めています。システムブラウザを利用すると、以下のメリットがあります。

  • ユーザーが IdP の既存セッション(Cookie)を再利用でき、再ログインが不要になる
  • パスワードマネージャーや生体認証との連携が機能する
  • アプリが認証情報を傍受できないため、セキュリティが向上する
危険

アプリ内の WebView(WKWebViewWebView 等)を認可リクエストに使用しないでください。WebView ではアプリがユーザーの入力やセッション Cookie を傍受できるため、RFC 8252 で非推奨とされています。

ただし、Web サービスの表示を目的とした WebView 内での認可フローはセッションバインドの仕組みで対応します。

redirect_uri の設計

redirect_uri にはプラットフォームの仕組みに応じて、以下のいずれかの形式を使用できます。

方式形式の例特徴
App Links (Android)https://app.example.com/callbackドメイン所有権の検証があり、他のアプリによる横取りが困難。推奨
Universal Links (iOS)https://app.example.com/callbackドメイン所有権の検証があり、セキュリティ上有利。ただし下記の注意を参照
カスタムスキームcom.example.myapp://callbackセットアップが容易だが、他のアプリが同じスキームを登録できるリスクがある

App Links / Universal Links を使用する場合、redirect_uri は通常の https:// URL となるため、RP のサーバーサイドコールバックと同じ見た目になりますが、OS がアプリに直接ルーティングします。

カスタムスキームを使用する場合は、他のアプリとの衝突を避けるためリバースドメイン形式(com.example.myapp://)を推奨します。

:::caution iOS での Universal Links ASWebAuthenticationSession を使用する場合、iOS のバージョンによっては Universal Links が期待どおりに動作しないことがあります。iOS では PKCE と併用したカスタムスキームが現実的な選択肢になる場合があります。対象の iOS バージョンに応じて動作を検証してください。 :::

PKCE による認可コード横取り防止

ネイティブアプリでは、コールバック URI を他のアプリが横取りするリスクがあります(特にカスタムスキーム使用時)。PKCE はこの攻撃を防ぐための最も重要な対策であり、Public Client では必須です。

code_verifier は暗号論的に安全な乱数から生成し、十分なエントロピー(256 ビット以上を推奨)を確保してください。

nonce による ID トークンのリプレイ防止

認可リクエストに nonce を含め、受け取った id_tokennonce クレームが一致することを検証してください。

state による CSRF 対策

認可リクエストごとにランダムな state 値を生成し、コールバック時に一致を検証してください。

トークンの安全な保管

  • アクセストークン・リフレッシュトークンは、OS が提供するセキュアストレージ(iOS の Keychain、Android の EncryptedSharedPreferences 等)に保管してください
  • トークンをログ出力やクラッシュレポートに含めないでください

2 回目以降のログイン

ユーザーが過去に同意済みで、要求する権限に変更がない場合、KLON は同意画面をスキップして自動的に認可コードを発行します。ただし、初回アクセス時は必ずアカウント確認画面が表示されます。

関連ページ