.NET MAUIとMAUI Blazor Appで生体認証（指紋認証）を実装してみる（Android）

# はじめに

Build 2022 にて現行のクロスプラットフォームである Xamarin.Forms の後継として、.NET MAUI（.NET Multi-platform App UI）が発表された。

![maui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633632/989f843f-3116-1592-e664-65461f8a9b0f.png)



https://dotnet.microsoft.com/en-us/apps/maui

ただし、リリースされたばかりということもあり、生体認証（指紋認証）を実装する知見があまりネットにはなかったため、備忘録としてまとめることにした。

以下のものを準備
- Visual Studio 2022 Preview
  - [MAUIの開発ワークロードをきちんとインストール](https://docs.microsoft.com/en-us/dotnet/maui/get-started/first-app?pivots=devices-android)しておく
  - Android エミュレータも用意しておく（本稿ではPixel5を私用）

# 検証内容

今回検証する内容としては、MAUIをベースとする以下の2つのプラットフォームで指紋認証を実装。
- MAUI app（[検証の際に参考にした文献](https://www.nuget.org/packages/Plugin.Fingerprint/#supportedframeworks-body-tab)）
- MAUI Blazor app

MAUI Blazor app について詳しくは[こちら](https://www.bing.com/search?q=maui+blazor+app&cvid=5ab56f8bcecc4aad984f990fc337caf4&aqs=edge..69i57j0l7j69i64.2813j0j1&pglt=41&FORM=ANNAB1&PC=U531)

# MAUI での指紋認証の実装
## Plugin.Fingerprintをインストール
MAUIプロジェクトを新規で立ち上げ、MAUIプロジェクトにNu GetでPlugin.Fingerprintをインストールする。バージョンは「プレリリースを含める」にチェックし、`3.0.0-bet.1` をインストール。

Plugin.Fingerprint：https://www.nuget.org/packages/Plugin.Fingerprint/#supportedframeworks-body-tab

## MAUIの環境設定
Xamarin.Formsで使用されていたパッケージをMAUIでも使えるように `Xamarin.Android.X` パッケージを Nu Get でインストール。インストール先は、MAUIプロジェクト＞Dependencies＞net6.0-android。

Android デバイスの生体認証機能にアクセスするために AndroidManifest.xml に以下を追記。
```
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<!-- only if you target android below level 28 -->
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
```

また、MainActivity.cs に以下を宣言。
```
using Plugin.Fingerprint;
...
protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    CrossFingerprint.SetCurrentActivityResolver(() => this);
}
```

## テンプレートのMainPage.xamlにボタンを作成
```
<ScrollView>
    <VerticalStackLayout 
        Spacing="25" 
        Padding="30,0" 
        VerticalOptions="Center">

        <Image
            Source="dotnet_bot.png"
            SemanticProperties.Description="Cute dot net bot waving hi to you!"
            HeightRequest="200"
            HorizontalOptions="Center" />
            
        <Label 
            Text="Hello, World!"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="32"
            HorizontalOptions="Center" />
        
        <Label 
            Text="Welcome to .NET Multi-platform App UI"
            SemanticProperties.HeadingLevel="Level2"
            SemanticProperties.Description="Welcome to dot net Multi platform App U I"
            FontSize="18"
            HorizontalOptions="Center" />

        <Button 
            x:Name="CounterBtn"
            Text="Click me"
            SemanticProperties.Hint="Counts the number of times you click"
            Clicked="OnCounterClicked"
            HorizontalOptions="Center" />

        <Button x:Name="AuthBtn" Text="Auth" Clicked="OnAuthClicked" HorizontalOptions="Center" />

    </VerticalStackLayout>
</ScrollView>
```

## イベントハンドラをMainPage.xaml.csに実装
```
using Plugin.Fingerprint;
using Plugin.Fingerprint.Abstractions;
…
private async void OnAuthClicked(object sender, EventArgs e)
{
    if (await CrossFingerprint.Current.IsAvailableAsync(true))
    {
        var request = new AuthenticationRequestConfiguration("Login!", "Access your account");
        var result = await CrossFingerprint.Current.AuthenticateAsync(request);
        if (result.Authenticated)
        {
            await DisplayAlert("Authenticated!", "Access granted", "OK");
        }
        else
        {
            await DisplayAlert("Not authenticated!", "Access denied", "OK");
        }
    }
    else
    {
        await DisplayAlert("Failure", "Biometrics not available", "OK");
    }
}
```

## デバイス側で指紋認証を事前登録
デバイス側に指紋が登録されていない状態でアプリを実行すると認証は失敗するので、デバイス（エミュレータ）側で事前に登録しておく。
- Android OS内の[設定]に移動し、[セキュリティ]を選択します
- [デバイスセキュリティ]で[画面ロック]を選択し、PINを追加します
- [デバイスセキュリティ]で[指紋]を選択して指紋を追加します。
  - エミュレータで指紋を追加するには、エミュレータ[…]をクリックして[指紋]を選択し、[センサーに触れる]ボタンを2回クリックします。2回クリックして、最後に[完了]をクリックします


## MAUI の動作検証

アプリ起動
![maui-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633632/bdcf012d-3e96-a20a-f97c-721c19e863e3.png)

Auth ボタン押下
![maui-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633632/08daed71-00a6-0d49-03ee-329b3f75c13e.png)

認証完了
![maui-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633632/40345175-dd79-b07a-59c4-6d46ffa1d566.png)


### MAUI のデモ動画はこちら
https://youtu.be/YmTfJdbMK4g


# MAUI Blazor での指紋認証の実装
MAUI Blazor app の場合は、BlazorWebView コンポーネントとの関係性を考慮する必要があるため、ボタンを配置するステップ3にて、テンプレートのMainPage.xamlを以下のように修正してみる。
```
<ScrollView>
    <VerticalStackLayout>
        
    <BlazorWebView HostPage="wwwroot/index.html">
        <BlazorWebView.RootComponents>
            <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
        </BlazorWebView.RootComponents>
    </BlazorWebView>

    <Button x:Name="AuthBtn" Text="Auth" Clicked="OnAuthClicked" HorizontalOptions="Center" />

    </VerticalStackLayout>
</ScrollView>
```

## MAUI Blazor の動作検証

Auth ボタン押下
![mauiblazor-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633632/405789de-c7d8-7311-ed05-6698387d6899.png)

認証完了
![mauiblazor-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633632/28248f6b-558b-86ff-9a56-d2c918ee49d7.png)


### MAUI Blazor のデモ動画はこちら
https://youtu.be/QudsJZV5OiM