Как мы в Тинькофф использовали Windows Hello для аутентификации пользователя

Windows Hello


Windows Hello — это технология биометрической аутентификации пользователя по отпечатку пальца, сетчатки глаза, трёхмерному сканированию лица и даже по венозной схеме ладони.

В сфере оказания финансовых услуг, важна безошибочная и безопасная аутентификация пользователя. Для авторизации мы используем двухфакторную систему из связки логина и пароля или номера телефона и пароля с подтверждением по коду, отправленному на привязанный номер мобильного телефона. Для дальнейшего упрощения доступа в авторизованную зону используется 4х значный ПИН-код.

После авторизации и создания ПИН-кода, аутентификацию пользователя можно переложить на плечи Windows Hello. Общая последовательность необходимых действий выглядит следующим образом:


  • Проверить возможность использования Windows Hello.
  • Проверка пользователя с помощью Windows Hello, что позволяет связать авторизованного Windows пользователя с нашим клиентом.
  • Кэширование созданного ранее ПИН-кода по идентификатору пользователя в защищённой области.
  • При последующих запусках приложения с авторизованным пользователем, автоматически запускается процедура аутентификации пользователя посредством Windows Hello. В случае успешной аутентификации из защищённой области запрашивается кэшированный ПИН-код.


Давайте рассмотрим каждый шаг подробнее на примерах кода.
Минимальным условием использования Windows Hello служит настроенный ПИН код доступа для входа в систему. В случае отсутствия у пользователя сертифицированного оборудования для биометрической аутентификации, будет использован ПИН код.

Мы это делаем так:

public async Task CheckHelloStatusAsync()
{
  var checkAvailabilityAsyncOperation = UserConsentVerifier.CheckAvailabilityAsync();
  var checkAvailabilityTask = checkAvailabilityAsyncOperation.AsTask();
  var completedTask = await Task.WhenAny(checkAvailabilityTask, Task.Delay(TimeSpan.FromSeconds(1)));
 
  if(completedTask == checkAvailabilityTask)
  {
    var availability = checkAvailabilityTask.Result;
 
    switch (availability)
    {
      case UserConsentVerifierAvailability.Available:
        return WindowsHelloStatus.Available;
      case UserConsentVerifierAvailability.DeviceBusy:
        return WindowsHelloStatus.Busy;
      case UserConsentVerifierAvailability.DisabledByPolicy:
        return WindowsHelloStatus.DisabledByPolicy;
      case UserConsentVerifierAvailability.NotConfiguredForUser:
        return WindowsHelloStatus.NotConfiguredForUser;
      default:
        return WindowsHelloStatus.Unavailable;
    }
  }
 
  checkAvailabilityAsyncOperation.Cancel();
  return WindowsHelloStatus.Unavailable;
}

Данный код не должен вызвать вопросов, здесь проверяется статус службы Windows Hello. UserConsentVerifierAvailability содержит чуть больше вариантов статуса службы, но для наших целей будет достаточно перечисленных в примере выше.

После установки пин-кода Тинькофф и успешной проверки доступности Windows Hello мы предлагаем пользователю подключить эту службу:

ggmmba3wpqgu0jgxgr9rp83ce80.gif


Если пользователь соглашается, то необходимо его аутентифицировать, для этого мы используем следующий код:

public async Task VerifyUserAsync()
{
  if (await CheckHelloStatusAsync() != WindowsHelloStatus.Available)
    return false;
 
  var result = await UserConsentVerifier.RequestVerificationAsync(requestMessage);
  return result == UserConsentVerificationResult.Verified;
}


В этом примере мы проверяем, что пользователь, использующий в данный момент устройство, тот же человек, что и владелец учётной записи. Как это сделать: UserConsentVerifier.RequestVerificationAsync — это метод, который берёт на себя проверку пользователя с помощью доступного варианта проверки, будь то аутентификация по отпечатку пальца, сетчатке глаза или любой другой способ. Удобство в том, что нам не приходится заботиться с помощью чего и как это происходит, главное, что такой вариант удовлетворяет нашим требованиям безопасности.

Без использования службы Windows Hello мы запрашиваем ввод пин-кода при каждом запуске приложения и долгом бездействии пользователя. Этот код используется для верификации запросов во время работы пользователя с приложением. В случае использования Windows Hello пользователю не нужно вводить этот код каждый раз и встаёт вопрос о безопасном хранении этого кода. Для этого на помощь приходит сервис PasswordVault, он позволяет хранить данные, требующие особого внимания к безопасности. Этот сервис не хранит данные в открытом виде. На устройствах, оборудованных специальным чипом для шифрования, сервис использует этот чип для защиты, на устройствах без чипа шифрования защита достигается программными средствами.

/// 
/// Добавление данных пользователя для запросов к серверу
/// 
/// Идентификатор пользователя
/// ПИН-код доступа
public void AddCredentials(string userId, string pin)
{
  var vault = new PasswordVault();
  vault.Add(new PasswordCredential(«Идентификатор Вашего приложения», userId, pin));
}


Этот пример показывает, как легко добавить данные в PasswordVault для хранения:

В случае смены или выхода пользователя в приложении необходимо выполнить удаление данных пользователя из хранилища паролей:

public void RemoveCredentials(string userId)
{
  var vault = new PasswordVault();
 
  var credentials = vault.Retrieve(«Идентификатор Вашего приложения», userId);
  if (credentials != null)
    vault.Remove(credentials);
}


В следующем примере представлен метод, который мы используем после запуска приложения:

public async Task SignInAsync(string userId)
{
  if (await CheckHelloStatusAsync() != WindowsHelloStatus.Available)
    return null;
 
  var result = await UserConsentVerifier.RequestVerificationAsync(requestMessage);
  if (result != UserConsentVerificationResult.Verified)
    return null;
 
  var vault = new PasswordVault();
  var credentials = vault.Retrieve(appCredentialsName, userId);
 
  return credentials?.Password;
}


Сначала мы проверяем, что служба Windows Hello доступна. Затем просим службу подтвердить, что приложение использует пользователь, владелец учётной записи. Если пользователь прошёл проверку, то мы извлекаем ПИН-код для этого пользователя, который был сохранён туда при установке пин-кода Тинькофф.

И вот, при помощи 5 небольших методов мы интегрировали Windows Hello в приложение.

© Habrahabr.ru