Android アプリ内のデジタル認証情報の検証は、ユーザーの身元(政府発行の身分証明書など)、そのユーザーに関するプロパティ(運転免許証、学位、年齢や住所などの属性など)、またはエンティティの真正性を確認するために認証情報の発行と検証が必要なその他のシナリオの認証と承認に使用できます。
デジタル認証情報は、デジタル ウォレットからユーザーの検証可能なデジタル認証情報にアクセスする方法を指定します。これは、公開 W3C インキュベーター標準であり、W3C 認証情報管理 API を使用してウェブのユースケース用に実装されています。Android では、デジタル認証情報の検証に Credential Manager の DigitalCredential
API が使用されます。
実装
Android プロジェクトでデジタル認証情報を確認する手順は次のとおりです。
- アプリのビルド スクリプトに依存関係を追加し、
CredentialManager
クラスを初期化します。 - デジタル認証情報リクエストを作成し、それを使用して
DigitalCredentialOption
を初期化してから、GetCredentialRequest
をビルドします。 - 作成したリクエストを使用して
getCredential
フローを起動し、成功したGetCredentialResponse
を受信するか、発生する可能性のある例外を処理します。取得に成功したら、レスポンスを検証します。
依存関係を追加して初期化する
Gradle ビルド スクリプトに次の依存関係を追加します。
dependencies {
implementation("androidx.credentials:credentials:1.5.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.5.0-beta01")
}
次に、CredentialManager
クラスのインスタンスを初期化します。
val credentialManager = CredentialManager.create(context)
デジタル認証情報リクエストを作成する
デジタル認証情報リクエストを作成し、DigitalCredentialOption
の初期化に使用します。
// The request in the JSON format to conform with
// the JSON-ified Digital Credentials API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
GetDigitalCredentialOption(requestJson = requestJson)
// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
listOf(digitalCredentialOption)
)
認証情報を取得する
作成したリクエストを使用して getCredential
フローを開始します。成功した場合は GetCredentialResponse
が返され、リクエストが失敗した場合は GetCredentialException
が返されます。
getCredential
フローでは、Android システム ダイアログがトリガーされ、ユーザーが利用可能な認証情報のオプションが表示され、ユーザーの選択が収集されます。次に、選択した認証情報オプションを含むウォレット アプリに UI が表示され、同意を収集し、デジタル認証情報レスポンスを生成するために必要なアクションを実行します。
coroutineScope.launch {
try {
val result = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
verifyResult(result)
} catch (e : GetCredentialException) {
handleFailure(e)
}
}
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
}
// Handle failure.
fun handleFailure(e: GetCredentialException) {
when (e) {
is GetCredentialCancellationException -> {
// The user intentionally canceled the operation and chose not
// to share the credential.
}
is GetCredentialInterruptedException -> {
// Retry-able error. Consider retrying the call.
}
is NoCredentialException -> {
// No credential was available.
}
is CreateCredentialUnknownException -> {
// An unknown, usually unexpected, error has occurred. Check the
// message error for any additional debugging information.
}
is CreateCredentialCustomException -> {
// You have encountered a custom error thrown by the wallet.
// If you made the API call with a request object that's a
// subclass of CreateCustomCredentialRequest using a 3rd-party SDK,
// then you should check for any custom exception type constants
// within that SDK to match with e.type. Otherwise, drop or log the
// exception.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}