LoginSignup
7
4

More than 1 year has passed since last update.

androidx.credentialsを利用して新たなパスワード管理を試す

Last updated at Posted at 2023-01-28

alphaが出たばかりなので、API等変更される可能性があります

新たなライブラリがリリースされた

2023年1月11日、androidx.credentials の1.0.0-alpha01 がリリースされました。
これはパスワードやパスキーなどを管理し、シームレスでセキュアなログイン体験を提供してくれるライブラリになっています。

本記事では実際にどういうことが可能かを試してみています。

関連クラス

CredentialManager

ユーザーの認証フローを管理するものです。
アプリはこのクラスにより、認証情報の登録や保存済みの認証情報の取得を、UIフローから利用することができます。

CredentialManager は端末で利用できる CredentialProvider に実際の処理を委譲します。

CredentialProvider

https://developer.android.com/reference/androidx/credentials/CredentialProvider
実際に認証情報の登録・取得処理を行っています。
これ自身はinterfaceで、OEMがライブラリなどとして実装することが想定されているようです。
ハードウェアメーカーが端末にセキュアに情報を保存する方法を提供するための方法ということでしょうか。

SDK version 33(Android 13)以下では開発者側はそのライブラリを依存に追加した上で、このインターフェースを実装するクラスをmeta-dataとして追加する必要があります。

SDK version 33より上では CredentialProvider の提供者はフレームワークに直接登録する形となるようです。

実装する

では実際に使ってみましょう。

依存関係

まずは依存関係に androidx.credentials を追加します。
実際に CredentialProvider の実装がなければ使えないので、現状使える credentials-play-ervices-auth も追加します。

build.gradle
dependencies {
    implementation 'androidx.credentials:credentials:1.0.0-alpha01'
    implementation 'androidx.credentials:credentials-play-services-auth:1.0.0-alpha01'
}

AndroidManifest

AndroidManifest には、どの CredentialProvider を使うかを登録します。
今回はPlayServiceのもの(Googleのパスワードマネージャー)を表すCredentialProviderPlayServicesImpl を指定します。

AndroidManifest.xml
<service android:name="androidx.credentials.playservices.CredentialProviderMetadataHolder">
  <meta-data
    android:name="androidx.credentials.CREDENTIAL_PROVIDER_KEY"
    android:value="androidx.credentials.playservices.CredentialProviderPlayServicesImpl" />
</service>

追記: CredentialProviderMetadataHolder の宣言はライブラリ側のAndroidManifestで行われています。
つまり androidx.credentials:credentials-play-services-auth が入っていれば勝手にAndroidManifestにマージされるため、自前で書く必要はありません。

認証情報登録

認証情報の登録は CredentialManager#executeCreateCredential() で行います。
id/パスワードが空文字だと例外が出るので注意します。
またUIを使ったフロー中にキャンセルされると例外が出るので処理します。

CredentialActivity.kt
lifecycleScope.launch {
  if(id.isNullOrEmpty() || password.isNullOrEmpty()) return@launch

  val request = CreatePasswordRequest(id, password)
  val credentialManager = CredentialManager.create(this)
  try {
    credentialManager.executeCreateCredential(request, this@CredentialActivity)
  } catch (e: CreateCredentialCancellationException) {
    Toast.makeText(this@CredentialActivity, "キャンセルされました", Toast.LENGTH_LONG).show()
  }
}

認証情報取得

認証情報の取得は CredentialManager#executeGetCredential() で行います。

認証情報は Bundle に入ってきますので、 PasswordCredential.BUNDLE_KEY_ID PasswordCredential.BUNDLE_KEY_PASSWORD で取得します。

また以下のケースで例外が投げられるのでこちらも処理します。

  • GetCredentialCancellationException
    • UI上で閉じるボタンを押すなどキャンセルされた場合
  • GetCredentialInterruptedException
    • このアプリに紐づく認証情報が保存されていない場合
CredentialActivity.kt
lifecycleScope.launch {
  val text = try {
    val request = GetCredentialRequest(listOf(GetPasswordOption()))
    val response = credentialManager.executeGetCredential(request, this@CredentialActivity)
    val credential = response.credential
    val id = credential.data.getString(PasswordCredential.BUNDLE_KEY_ID, "")
    val password = credential.data.getString(PasswordCredential.BUNDLE_KEY_PASSWORD, "")
"id: $id pass: $password"
  } catch (e: GetCredentialCancellationException) {
    "キャンセルされました"
  } catch (e: GetCredentialInterruptedException) {
    "エラーが発生しました"
  }
  Toast.makeText(this@CredentialActivity, text, Toast.LENGTH_LONG).show()
}

完成

実際にUIも含めて作ったのがこちら。
https://github.com/verno3632/WorkingDog/tree/main/credential

認証情報保存の際に、Googleのパスワードマネージャーに登録されます。
set.gif

同様にパスワードマネージャーから取得もできます
get.gif

パスワードマネージャーを覗いてみると、アプリのパッケージ名(アプリケーションID)で保存されていました。
もちろん端末を跨いで共有することが出来ます。

終わりに

まだ1.0.0-alpha01ということで、絶賛開発中のようです。コード中にもTODOの部分が多くありました。

33以下では認証情報管理のライブラリを明示的に依存関係に追加しなければいけませんが、34以上では扱いが違うようなことがドキュメントから読み取れます。
34以上で端末で利用できるパスワードマネージャーからユーザーが好きに選択して使えるとかになるなど、Androidへの機能追加があるんじゃないか?と思ってます。

今後とも注視していきたいですね :eyes:

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4