MobileIntegrating Fingerprint Authentication with App Login for iOS and Android

Integrating Fingerprint Authentication with App Login for iOS and Android

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

One of the common use cases is to enable fingerprint login for an app. This adds additional security and also makes it convenient to use. Fingerprint scanning is platform specific; however, in this article we will use a plug-in available for Xamarin Forms to enable fingerprint detection.

Description

To begin with, create a solution using the template ‘Multiplatform’ –> Forms App. In this example, we name it ‘FingerprintDemo.’ Add the ‘Plugin.Fingerprint‘ package to the cross-platform forms and also to the device-specific projects.

In this sample application, we will create an authentication page, where the user will key in the credentials to log in to the app. The app uses the saved fingerprint information on the device. The app saves the user login details for the first time. Future logins are enabled by using the fingerprint login and the saved credentials. If the credentials or the fingerprint don’t validate, the user is required to key in the credentials again.

Xamarin Forms Level Changes

Create a new XAML form that will be the login page. This will be the starting point of the app. In the XAML, add two entry fields to key in the username/password. Add a button that lets the user authenticate. We will wrap the entry fields in the stack layout to hide or show the section based on whether or not the fingerprint login is available. If fingerprint login is available, the user just presses the ‘Login’ button.

<StackLayout>
   <Label Text="Authentication" VerticalOptions="Center"
      HorizontalOptions="Center" />
   <StackLayout x_Name="inputContainer">
      <Entry Placeholder="Username" x_Name="txtUsername" />
      <Entry Placeholder="Password" IsPassword="true"
         x_Name="txtPassword" />
   </StackLayout>
   <Button Clicked="OnLogin_Clicked" x_Name="btnLogin"
      Text="Login" />
</StackLayout>

In the code behind file, we declare the following properties:

   public string Username { get; set; }
   public string Password { get; set; }
   public bool IsFingerprintLoginAvailableForUser { get; set; }
   private bool _storedCredentialsExists { get; set; }

In the constructor, add the following code to initialize the application:

   var init = Init();
   init.Wait();

Define a method named ‘Init,’ as shown below:

   public async Task Init()
   {
      // Check if the user has stored credentials from a
      // prior login
      if (Application.Current.Properties.ContainsKey("Username"))
      {
         _storedCredentialsExists = true;
      }
      var fingerprintSupported = await
         CrossFingerprint.Current.IsAvailableAsync();
      IsFingerprintLoginAvailableForUser = fingerprintSupported
         && _storedCredentialsExists;

      if(IsFingerprintLoginAvailableForUser)
      {
         inputContainer.IsVisible = false;
      }

   }

This method checks whether the user credentials are stored in the application properties. It also checks if the fingerprint is supported.

In the login button clicked event, add the following code:

 1. public void OnLogin_Clicked(object sender, System.EventArgs e)
 2. {
 3.    if (IsFingerprintLoginAvailableForUser)
 4.    {
 5.       Task.Run(async () => { await Authenticate(); });
 6.    }
 7.    else
 8.    {
 9.       if (Application.Current.Properties
                .ContainsKey("Username"))
10.          Application.Current.Properties["Username"] =
                txtUsername.Text;
11.       else
12.          Application.Current.Properties.Add("Username",
                txtUsername.Text);

13.       if (Application.Current.Properties
                .ContainsKey("Password")
14.          Application.Current.Properties["Password"] =
                txtPassword.Text;
15.       else
16.          Application.Current.Properties.Add("Password",
                txtPassword.Text);
17.
18.       if (
19.          ValidateUsernamePassword(
20.             Application.Current.Properties["Username"]
                   .ToString(),
                Application.Current.Properties["Password"]
                   .ToString()))
                {
                   // Navigate to the home/landing page

                }
          else
          {
             Task.Run(async () =>
             {
                await DisplayAlert("Login Error",
                   "Invalid Username/Password", "Cancel");
                // Disable biometric login
                IsFingerprintLoginAvailableForUser = false;
             });
          }
       }
    }

The code checks if the fingerprint login is available for the user. If yes, it executes the ‘Authenticate’ method. If there is no fingerprint available, it stores the currently entered username/password to the application properties.

The “Authenticate” method definition is as demonstrated below:

1. public async Task Authenticate()
2. {
3.    if (IsFingerprintLoginAvailableForUser)
4.    {
5.       // Configure the fingerprint request dialog
6.       var biometricConfig = new
            AuthenticationRequestConfiguration("Fingerprint Auth")
            {
               CancelTitle = "Cancel",
               FallbackTitle = "Done"
            };
7.       var biometricResult = await CrossFingerprint.Current
               .AuthenticateAsync
            (biometricConfig);

         if (biometricResult.Authenticated)
         {

            if (ValidateUsernamePassword(
               Application.Current.Properties["Username"]
                  .ToString(),
               Application.Current.Properties["Password"]
                  .ToString()))
            {
               // Navigate to the home/landing page

            }
            else
            {
               await DisplayAlert("Login Error",
                  "Invalid UserName/Password", "Cancel");

                  IsFingerprintLoginAvailableForUser = false;
                  inputContainer.IsVisible = true;
            }
         }
         else if (biometricResult.Status ==
            FingerprintAuthenticationResultStatus.UnknownError)
         {
            await DisplayAlert("Error",
               biometricResult.ErrorMessage, "Cancel");
         }
      }
   }

Line 6 of the ‘Authenticate’ method configures the fingerprint request dialog and Line 7 prompts the dialog for the fingerprint authentication. When the user presses their finger against the fingerprint reader, it validates the fingerprint. If fingerprint is authenticated, it authenticates the app with the stored credential information and navigates the user to the next page.

Summary

In a real scenario, the user can be authenticated against an STS or any other authentication provider. In this article, we saved the credentials in the application; instead, we also can store the refresh token that can be used to issue a new authentication token.

Reference

https://www.nuget.org/packages/Plugin.Fingerprint/

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories