MAUIで作成したスマホアプリにおいて、生体認証の実装をAIに教えてもらいながら試してみた。とりあえず成功したので、やったことを忘備録としてまとめておく
※今回がうまくいったというだけで、必要十分ではないかもしれない
概要
この記事では、.NET MAUI で作成したスマホアプリに
指紋認証/顔認証(PINフォールバックあり)を実装する手順をまとめます。
以下の2つのステップが必要
- 準備:ライブラリと設定
- 実際に動かす部分の実装
1. 準備:ライブラリと設定
インストール
NuGetで以下のパッケージをインストール Plugin.Maui.Biometric する
これだとAndroidとiOSを個別に実装しなくてすむ
最初、LLMが Plugin.Fingerprint をすすめてきたが、これはiOS未対応だった
Android設定
Platforms/Android/AndroidManifest.xml の manifest タグの直下に以下を追加
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
私の環境ではGUIで設定できた
「必要なアクセス許可」をスクロールして「USE_BIOMETRIC」と「USE_FINGERPRINT」をチェック
iOS設定
Platforms/iOS/Info.plist の dict タグの中に以下を追加
<key>NSFaceIDUsageDescription</key>
<string>ログイン情報を安全に呼び出すために顔認証を使用します。</string>
VisualStudio上でInfo.plistをダブルクリックするとGUIの設定画面が開いてしまう
右クリックで「エクスプローラーで開く」をし、VSCodeで開いて直接追加した
(GUIからもいけるのかもしれないけど、よくわからない。とりあえず直接追加でいけた)
実際に動かす部分の実装
実際に動かすページにコードを追加。必要なタイミングで呼び出す
using Plugin.Maui.Biometric; // 生体認証
// ・・・・・
private async Task CheckAuthAndLoadValues()
{
// 1. ステータス確認
var status = await BiometricAuthenticationService.Default.GetAuthenticationStatusAsync();
switch (status)
{
case BiometricHwStatus.Success:
// 問題なし
break;
case BiometricHwStatus.NotEnrolled:
// 生体認証やPINが未登録の場合
await DisplayAlertAsync("設定が必要です", "端末に指紋やPINが登録されていません。端末の設定からセキュリティ設定を行ってください。", "OK");
return;
case BiometricHwStatus.Unavailable:
// iOSなどで権限を拒否された場合
await DisplayAlertAsync("権限エラー", "アプリでの認証が許可されていません。設定アプリから認証を許可してください。", "OK");
return;
case BiometricHwStatus.NoHardware:
// ハードが認識されないが、PINならいける可能性がある場合
// ここではあえて return せずに、下の AuthenticateAsync に進ませる
break;
default:
await DisplayAlertAsync("エラー", $"認証を利用できません: {status}", "OK");
return;
}
// 2. 認証リクエストの設定
var request = new AuthenticationRequest
{
Title = "本人確認",
Description = "認証してください",
NegativeText = "キャンセル",
// 指紋センサーが認識されない場合、端末のPIN/パスワード入力画面を出す
AllowPasswordAuth = true
};
try
{
// 3. 認証を実行
var result = await BiometricAuthenticationService.Default.AuthenticateAsync(request, CancellationToken.None);
// 4. 結果の判定
if (result.Status == BiometricResponseStatus.Success)
{
// 成功時の処理
}
else
{
// 失敗理由を表示(デバッグのヒント)
await DisplayAlertAsync("認証失敗", $"理由: {result.Status}", "OK");
}
}
catch (Exception ex)
{
await DisplayAlertAsync("エラー", "認証システムを起動できませんでした。", "OK");
}
}
その他メモ
- 一部のAndroidでうまく動かない
→ NoHardwareでretrunさせずにPINで認証させる
※ 絶対に生体認証をさせたいならここでreturn