認証情報マネージャーで認証情報の復元を実装する

このページでは、復元キーの作成、復元キーを使用したログイン、復元キーの削除の方法について説明します。

バージョンの互換性

認証情報マネージャーの復元認証情報は、Android 9 以降、Google Play 開発者サービス(GMS)コア バージョン 24220000 以降、androidx.credentials ライブラリ バージョン 1.5.0 以降を搭載したデバイスで動作します。

前提条件

パスキーのサーバーと同様に、証明書利用者サーバーを設定します。パスキーを使用した認証を処理する サーバーがすでに設定されている場合は、 復元キーにも同じサーバーサイド実装を使用します。

依存関係

アプリ モジュールの build.gradle ファイルに次の依存関係を追加します。

Kotlin

dependencies {
    implementation("androidx.credentials:credentials:1.7.0-alpha02")
    implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha02")
}

Groovy

dependencies {
    implementation "androidx.credentials:credentials:1.7.0-alpha02"
    implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
}

復元認証情報は、androidx.credentials ライブラリ バージョン 1.5.0 以降で使用できます。ただし、可能な限り、依存関係の最新の安定版を使用することをおすすめします。

概要

  1. 復元キーを作成する: 復元キーを作成する手順は次のとおりです。
    1. 認証情報マネージャーをインスタンス化する: CredentialManager オブジェクトを作成します。
    2. アプリサーバーから認証情報作成オプションを取得する: アプリサーバーから復元キーの作成に必要な詳細情報を クライアント アプリに送信します 。
    3. 復元キーを作成する: ユーザーがアプリにログインしている場合は、ユーザーの アカウントの復元キーを作成します。
    4. 認証情報作成レスポンスを処理する: クライアント アプリからアプリサーバーに認証情報を送信して処理し、例外を処理します。
  2. **復元キーを使用してログインする**: 復元キーを使用してログインする手順は次のとおりです。
    1. アプリサーバーから認証情報取得オプションを取得する: アプリサーバーから復元キーの取得に必要な詳細情報を クライアント アプリに送信します。
    2. 復元キーを取得する: ユーザーが新しいデバイスを設定するときに、認証情報 マネージャーに復元キーをリクエストします。これにより、ユーザーは追加の入力をせずにログインできます。
    3. 認証情報取得レスポンスを処理する: クライアント アプリからアプリサーバーに復元キー を送信して、ユーザーをログインさせます。
  3. 復元キーを削除する

復元キーを作成する

アクティブ ユーザーに復元キーが作成されるように、アプリはユーザーのログインのすべてのケースに対応する必要があります。復元キーは、次のシナリオで作成します。

  • ユーザーがログインしていて、復元キーがまだ作成されていない場合(メイン ActivityonCreate メソッドなど)。
  • ユーザーがログインしている場合、または新しいアカウント登録フローを完了している場合。

パフォーマンスを最適化し、ログインするたびに復元認証情報を作成または確認するオーバーヘッドを回避するには、boolean フラグまたは認証情報作成タイムスタンプをローカル ストレージ(has_synced_restore_credential など)に設定して、キーがすでに作成されているかどうかを追跡します。

認証情報マネージャーをインスタンス化する

アプリのアクティビティ コンテキストを使用して、CredentialManager オブジェクトをインスタンス化します。

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

アプリサーバーから認証情報作成オプションを取得する

アプリサーバーで FIDO 準拠のライブラリを使用して、ユーザー、アプリ、追加の構成プロパティなどの復元認証情報の作成に必要な情報をクライアント アプリに送信します。サーバーサイドの実装について詳しくは、サーバーサイド のガイダンスをご覧ください

復元キーを作成する

サーバーから送信された公開鍵作成オプションを解析したら、これらのオプションを CreateRestoreCredentialRequest オブジェクトにラップし、CredentialManager オブジェクトを使用して createCredential() メソッドを呼び出して、 復元キーを作成します。

// createRestoreRequest contains the details sent by the server 
val response = credentialManager.createCredential(context, createRestoreRequest)

コードに関する主なポイント

  • CreateRestoreCredentialRequest オブジェクトには次のフィールドがあります。

    • requestJson:アプリサーバーから送信された認証情報作成オプション。 Web Authentication API 形式の PublicKeyCredentialCreationOptionsJSONです。
    • isCloudBackupEnabled: 復元キーをクラウドにバックアップするかどうかを判断する Boolean フィールド。デフォルトでは、このフラグは true です。このフィールドには次の値があります。

      • true: (推奨 )ユーザーが Google バックアップとエンドツーエンドの暗号化(画面ロックなど)を有効にしている場合、この値により復元キーのクラウドへのバックアップが有効になります。
      • false: この値は、キーをクラウドではなくローカルに保存します。ユーザーがクラウドから復元することを選択した場合、新しいデバイスでキーを使用できません。

認証情報作成レスポンスを処理する

Credential Manager API は、タイプ CreateRestoreCredentialResponseのレスポンスを返します。このレスポンスには、公開鍵 認証情報の登録レスポンスが JSON 形式で保持されます。

アプリから証明書利用者サーバーに公開鍵を送信します。この公開鍵は、パスキーの作成時に生成される公開鍵に似ています。サーバーでパスキーの作成を処理するのと同じコードで、復元キーの作成を処理することもできます。サーバーサイドの実装について詳しくは、the パスキーのガイダンスをご覧ください。

復元キーの作成プロセス中に、次の例外を処理します。

  • CreateRestoreCredentialDomException: requestJson が無効で、 PublicKeyCredentialCreationOptionsJSON の WebAuthn 形式に準拠していない場合に発生します。
  • E2eeUnavailableException: isCloudBackupEnabledtrue であっても、ユーザーのデバイスにデータ バックアップまたはエンドツーエンドの暗号化(画面ロックなど)がない場合に発生します。
    復元認証情報がすべての場合に作成されるようにするには、isCloudBackupEnabledtrue に設定して createCredential を呼び出すことで、E2eeUnavailableException を明示的に処理する必要があります。E2eeUnavailableException がスローされた場合は、キャッチして isCloudBackupEnabledfalse に設定して createCredential を再度呼び出します。
  • IllegalArgumentException: createRestoreRequest が空であるか、有効な JSON ではない場合、または WebAuthn 仕様に準拠した有効な user.idがない場合に発生します。

復元キーを使用してログインする

デバイスの設定プロセス中に、復元認証情報を使用してユーザーをサイレント ログインさせます。

アプリサーバーから認証情報取得オプションを取得する

サーバーから復元キーを取得するために必要なオプションをクライアント アプリに送信します。 この手順のパスキーに関する同様のガイダンスについては、パスキーを使用してログインするをご覧ください。 サーバーサイドの実装について詳しくは、サーバーサイド 認証ガイドをご覧ください。

復元キーを取得する

新しいデバイスで復元キーを取得するには、CredentialManager オブジェクトで getCredential() メソッドを呼び出します。

次の両方のシナリオで復元キーを取得することをおすすめします。

  • デバイスでアプリを初めて起動したとき。このシナリオでの認証情報の復元は、アプリデータの復元とは独立しています。
  • アプリデータのバックアップと復元が有効になっている場合は、アプリデータの復元直後に復元キーを取得します。BackupAgent を使用してアプリのバックアップを構成し、getCredential 機能を onRestoreFinished コールバック内で完了します。onRestore メソッドは Key-Value バックアップでのみ呼び出されますが、 onRestoreFinished はあらゆる種類のバックアップ復元で確実に呼び出されるため、onRestore メソッドは使用しないでください。これにより、ユーザーが新しいデバイスを初めて開いたときに遅延が発生する可能性を回避し、ユーザーがアプリを開くのを待たずにアプリを操作できるようにします。たとえば、これにより、ユーザーが新しいデバイスでアプリを初めて開く前に、アプリからユーザーに通知を送信できます。これは、メッセージング アプリやコミュニケーション アプリに特に適しています。
// Fetch the options required to get the restore key
val authenticationJson = fetchAuthenticationJson()

// Create the GetRestoreCredentialRequest object
val options = GetRestoreCredentialOption(authenticationJson)
val getRequest = GetCredentialRequest(listOf(options))

val response = credentialManager.getCredential(context, getRequest)

// Type-check and extract the restore credential
val credential = response.credential as RestoreCredential

認証情報マネージャー API は、 GetCredentialResponse タイプのレスポンスを返します。このレスポンスに含まれる認証情報は、公開鍵を保持する RestoreCredential タイプです。

ログイン レスポンスを処理する

アプリから証明書利用者サーバーに公開鍵を送信します。この公開鍵を使用してユーザーをログインさせることができます。サーバー側では、このアクションはパスキーを使用したログインに似ています。サーバーでパスキーを使用したログインを処理するのと同じコードで、復元キーを使用したログインを処理することもできます。パスキーのサーバーサイド実装について詳しくは、パスキーを使用してログインするをご覧ください。

復元キーを削除する

認証情報マネージャーはステートレスで、ユーザー アクティビティを認識しないため、使用後に復元キーを自動的に削除しません。復元キーを削除するには、clearCredentialState() メソッドを呼び出します。セキュリティのため、ユーザーがログアウトするたびにキーを削除してください。これにより、ユーザーが同じデバイスでアプリを次回開いたときに、ユーザーがログアウトし、再度ログインするように求められます。

アプリをアンインストールすることは、ユーザーがログアウトするときと同様に、そのデバイスから対応する復元キーを削除する意図があると解釈されます。

復元キーは、次の場合にのみ削除されます。

  • システムレベルのアクション: ユーザーがアプリをアンインストールするか、アプリのデータを消去します。
  • アプリレベルの呼び出し: アプリのコードでユーザーのログアウトを処理するときに clearCredentialState()を呼び出して、プログラムでキーを削除します。

ユーザーがアプリからログアウトしたら、CredentialManager オブジェクトで clearCredentialState() メソッドを呼び出します。

// Create a ClearCredentialStateRequest object
val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)

// When the user logs out, delete the restore key
val response = credentialManager.clearCredentialState(clearRequest)