Поделиться через


Добавление проверки подлинности в приложение Uno Platform

В этом руководстве описано, как добавить проверку подлинности Майкрософт в проект TodoApp с помощью идентификатора Microsoft Entra. Прежде чем завершить работу с этим руководством, убедитесь, что вы создали проект и развернули серверную часть.

Совет

Хотя мы используем идентификатор Microsoft Entra для проверки подлинности, вы можете использовать любую библиотеку проверки подлинности, которую вы хотите использовать с мобильными приложениями Azure.

Добавление проверки подлинности в серверную службу

Серверная служба — это стандартная служба ASP.NET 6. В любом руководстве показано, как включить проверку подлинности для службы ASP.NET 6, которая работает с мобильными приложениями Azure.

Чтобы включить проверку подлинности Microsoft Entra для серверной службы, необходимо:

  • Регистрация приложения с Microsoft Entra ID.
  • Добавьте проверку подлинности проверка в проект серверной части ASP.NET 6.

Регистрация приложения

Сначала зарегистрируйте веб-API в клиенте Microsoft Entra и добавьте область, выполнив следующие действия:

  1. Войдите на портал Azure.

  2. Если у вас есть доступ к нескольким клиентам, используйте фильтр каталогов и подписок в верхнем меню, чтобы переключиться на клиент, в котором требуется зарегистрировать приложение.

  3. Найдите и выберите Microsoft Entra ID.

  4. В разделе Управление выберите Регистрация приложений>Создать регистрацию.

    • Имя: введите имя приложения, например Краткое руководство по TodoApp. Пользователи приложения увидят это имя. Его можно будет изменить впоследствии.
    • Поддерживаемые типы учетных записей: учетные записи в любом каталоге организации (любой каталог Microsoft Entra — Multitenant) и личные учетные записи Майкрософт (например, Skype, Xbox)
  5. Выберите Зарегистрировать.

  6. В разделе Управление выберите Предоставление API>Добавить группу.

  7. Для URI идентификатора приложения примите значение по умолчанию, нажав кнопку "Сохранить" и продолжить.

  8. Введите следующие сведения:

    • Имя области: access_as_user
    • Кто может предоставить согласие?: Администратор и пользователи
    • Отображаемое имя согласия администратора: Access TodoApp
    • Описание согласия администратора: Allows the app to access TodoApp as the signed-in user.
    • Отображаемое имя согласия пользователя: Access TodoApp
    • Описание согласия пользователя: Allow the app to access TodoApp on your behalf.
    • Состояние: включено
  9. Выберите Добавить область, чтобы завершить добавление области.

  10. Обратите внимание на значение область, аналогичное api://<client-id>/access_as_user (называемой областью веб-API). Вам потребуется область при настройке клиента.

  11. Выберите Обзор.

  12. Обратите внимание на идентификатор приложения (клиента) в разделе Essentials (идентификатор приложения веб-API). Это значение необходимо для настройки серверной службы.

Откройте Visual Studio и выберите TodoAppService.NET6 проект.

  1. Щелкните проект правой TodoAppService.NET6 кнопкой мыши и выберите пункт "Управление пакетами NuGet...".

  2. На новой вкладке нажмите кнопку "Обзор", а затем в поле поиска введите Microsoft.Identity.Web .

    Screenshot of adding the M S A L NuGet in Visual Studio.

  3. Microsoft.Identity.Web Выберите пакет, а затем нажмите кнопку "Установить".

  4. Следуйте инструкциям, чтобы завершить установку пакета.

  5. Открыть Program.cs. Добавьте следующее в список операторов using :

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
  1. Добавьте следующий код непосредственно над вызовом builder.Services.AddDbContext():
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
  1. Добавьте следующий код непосредственно над вызовом app.MapControllers():
app.UseAuthentication();
app.UseAuthorization();

Ваш Program.cs теперь должен выглядеть так:

using Microsoft.AspNetCore.Datasync;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using TodoAppService.NET6.Db;
  
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
  
if (connectionString == null)
{
  throw new ApplicationException("DefaultConnection is not set");
}
  
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDatasyncControllers();
  
var app = builder.Build();
  
// Initialize the database
using (var scope = app.Services.CreateScope())
{
  var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
  await context.InitializeDatabaseAsync().ConfigureAwait(false);
}
  
// Configure and run the web service.
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
  1. Измените Controllers\TodoItemController.csобъект . [Authorize] Добавьте атрибут в класс. Класс должен выглядеть следующим образом:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Datasync;
using Microsoft.AspNetCore.Datasync.EFCore;
using Microsoft.AspNetCore.Mvc;
using TodoAppService.NET6.Db;

namespace TodoAppService.NET6.Controllers
{
  [Authorize]
  [Route("tables/todoitem")]
  public class TodoItemController : TableController<TodoItem>
  {
    public TodoItemController(AppDbContext context)
      : base(new EntityTableRepository<TodoItem>(context))
    {
    }
  }
}
  1. Измените appsettings.jsonобъект . Добавьте следующий блок:
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },

Замените <client-id>идентификатор приложения веб-API, записанный ранее. После завершения он должен выглядеть следующим образом:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TodoApp;Trusted_Connection=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Опубликуйте службу в Azure еще раз:

  1. Щелкните проект правой TodoAppService.NET6 кнопкой мыши и выберите "Опубликовать...".
  2. Нажмите кнопку "Опубликовать" в правом верхнем углу вкладки.

Откройте в браузере страницу https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0. Обратите внимание, что служба теперь возвращает ответ, указывающий 401 , что требуется проверка подлинности.

Screenshot of the browser showing an error.

Регистрация приложения в службе удостоверений

Платформа синхронизации данных Майкрософт имеет встроенную поддержку для любого поставщика проверки подлинности, использующего веб-токен Json (JWT) в заголовке транзакции HTTP. Это приложение использует библиотеку проверки подлинности Майкрософт (MSAL) для запроса такого маркера и авторизации пользователя, выполнившего вход в серверную службу. Дополнительные сведения об интеграции MSAL в проект Uno Platform см . в их документации;

Настройка собственного клиентского приложения

Вы можете зарегистрировать собственные клиенты, чтобы разрешить проверку подлинности размещенных в приложении веб-API с помощью клиентской библиотеки, такой как Библиотека идентификации Майкрософт (MSAL).

  1. В портал Azure выберите идентификатор Microsoft Entra ID> Регистрация приложений> New.

  2. На странице регистрации приложения:

    • введите имя для регистрации приложения. Вы можете использовать имя native-quickstart , чтобы отличить его от того, который используется серверной службой.
    • Выберите учетные записи в любом каталоге организации (любой каталог Microsoft Entra — Multitenant) и личных учетных записей Майкрософт (например, Skype, Xbox).
    • В URI перенаправления:
      • Выбор общедоступного клиента (мобильный и настольный компьютер)
      • Введите URL-адрес quickstart://auth
  3. Выберите Зарегистрировать.

  4. Выберите Разрешения API>Добавить разрешение>Мои API.

  5. Выберите регистрацию приложения, созданную ранее для серверной службы. Если вы не видите регистрацию приложения, убедитесь, что вы добавили access_as_user область.

    Screenshot of the scope registration in the Azure portal.

  6. В разделе "Выбор разрешений" выберите access_as_user и нажмите кнопку "Добавить разрешения".

  7. Выберите мобильные и классические приложения проверки подлинности>.

  8. Установите флажок рядом с https://login.microsoftonline.com/common/oauth2/nativeclient.

  9. Установите флажок рядом msal{client-id}://auth с полем (замена {client-id} идентификатором приложения).

  10. Выберите "Добавить URI", а затем добавьте http://localhost в поле дополнительные URI.

  11. В нижней части страницы нажмите кнопку Сохранить.

  12. Выберите Обзор. Запишите идентификатор приложения (клиента), который называется идентификаторомсобственного клиентского приложения, так как он необходим для настройки мобильного приложения.

Мы определили три URL-адреса перенаправления:

  • http://localhost используется приложениями WPF.
  • https://login.microsoftonline.com/common/oauth2/nativeclient используется приложениями UWP.
  • msal{client-id}://auth используется мобильными приложениями (Android и iOS).

Добавление клиента удостоверений Майкрософт в приложение

Откройте решение TodoApp.sln в Visual Studio. Добавьте uno.WinUI.MSAL в каждый из проектовTodoApp.Uno:

  1. Щелкните решение правой кнопкой мыши и выберите пункт "Управление пакетами NuGet для решения...".

  2. Откройте вкладку Browse (Обзор).

  3. В окне поиска введите Uno.WinUI.MSAL и нажмите клавишу ВВОД.

  4. Uno.WinUI.MSAL Выберите результат.

  5. На правой панели выберите каждый из проектов TodoApp.Uno .

  6. Выберите Установить.

    Screenshot of selecting the Uno MSAL NuGet in Visual Studio.

  7. Примите условия лицензионного соглашения, чтобы продолжить установку.

Используйте тот же метод, чтобы добавить библиотеку Microsoft.Identity.Client в каждый из проектов TodoApp.Uno :

  1. В окне поиска введите Microsoft.Identity.Client и нажмите клавишу ВВОД.

  2. Microsoft.Identity.Client Выберите результат.

  3. На правой панели выберите каждый из проектов TodoApp.Uno .

  4. Выберите Установить.

    Screenshot of selecting the MSAL NuGet in Visual Studio.

  5. Примите условия лицензионного соглашения, чтобы продолжить установку.

Примечание.

Убедитесь, что установлены последние версии этих двух библиотек. Минимальные номера версий:

  • Uno.WinUI.MSAL версии 4.9.20
  • Microsoft.Identity.Client версии 4.54.1

Добавьте собственный идентификатор клиента и серверную область в конфигурацию.

Откройте проект и измените TodoApp.DataConstants.cs файл. Добавление констант для ApplicationId и Scopes:

  public static class Constants
  {
      /// <summary>
      /// The base URI for the Datasync service.
      /// </summary>
      public static string ServiceUri = "https://demo-datasync-quickstart.azurewebsites.net";

      /// <summary>
      /// The application (client) ID for the native app within Azure Active Directory
      /// </summary>
      public static string ApplicationId = "<client-id>";

      /// <summary>
      /// The list of scopes to request
      /// </summary>
      public static string[] Scopes = new[]
      {
          "<scope>"
      };
  }

<client-id>Замените идентификатор собственного клиентского приложения, полученный при регистрации клиентского приложения в идентификаторе Microsoft Entra ID, и <scope>область веб-API, скопированную при использовании API при регистрации приложения-службы.

MainPage.xaml.cs Откройте файл в верхней папке TodoApp.Uno проекта.

Добавьте следующие операторы using в начало файла:

using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
using System.Linq;
using Uno.UI.MSAL;

Замените поля и конструктор следующим кодом:

    private readonly IPublicClientApplication _identityClient;
    private readonly TodoListViewModel _viewModel;
    private readonly ITodoService _service;

    public MainPage() {
        this.InitializeComponent();

        _identityClient = PublicClientApplicationBuilder
            .Create(Constants.ApplicationId)
            .WithAuthority(AzureCloudInstance.AzurePublic, "common")
#if __IOS__ || __MACOS__ || __ANDROID__
            .WithRedirectUri($"msal{Constants.ApplicationId}://auth")
#else
            .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
#endif
#if __IOS__
            .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
#endif
            .WithUnoHelpers()
            .Build();
        _service = new RemoteTodoService(GetAuthenticationToken);
        _viewModel = new TodoListViewModel(this, _service);
        mainContainer.DataContext = _viewModel;
    }

Добавьте следующий метод в MainPage класс:

    public async Task<AuthenticationToken> GetAuthenticationToken()
    {
        var accounts = await _identityClient.GetAccountsAsync();
        AuthenticationResult? result = null;
        bool tryInteractiveLogin = false;

        try
        {
            result = await _identityClient
                .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
                .ExecuteAsync();
        }
        catch (MsalUiRequiredException)
        {
            tryInteractiveLogin = true;
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"MSAL Silent Error: {ex.Message}");
        }

        if (tryInteractiveLogin)
        {
            try
            {
                result = await _identityClient
                    .AcquireTokenInteractive(Constants.Scopes)
                    .WithUnoHelpers()
                    .ExecuteAsync();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"MSAL Interactive Error: {ex.Message}");
            }
        }

        return new AuthenticationToken
        {
            DisplayName = result?.Account?.Username ?? string.Empty,
            ExpiresOn = result?.ExpiresOn ?? DateTimeOffset.MinValue,
            Token = result?.AccessToken ?? string.Empty,
            UserId = result?.Account?.Username ?? string.Empty
        };
    }

Метод GetAuthenticationToken() работает с библиотекой удостоверений Майкрософт (MSAL), чтобы получить маркер доступа, подходящий для авторизации вошедшего пользователя в серверную службу. Затем эта функция передается RemoteTodoService в клиент для создания клиента. Если проверка подлинности выполнена успешно, создается данные, AuthenticationToken необходимые для авторизации каждого запроса. Если нет, вместо этого создается неправильный маркер с истекшим сроком действия.

Настройка приложения Android для проверки подлинности

TodoApp.Uno.Mobile Откройте проект и разверните папкуAndroid. Создайте новый класс MsalActivity.Android.cs (наряду с существующим MainActivity.Android.cs) со следующим кодом:

using Android.Content;
using Microsoft.Identity.Client;

namespace TodoApp.Uno.Droid
{
    [Activity(Exported = true)]
    [IntentFilter(new[] { Intent.ActionView },
       Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
       DataHost = "auth",
       DataScheme = "msal{client-id}")]
    public class MsalActivity : BrowserTabActivity
    {
    }
}

Замените {client-id} идентификатором приложения собственного клиента (то же самое, что Constants.ApplicationIdи ).

Если проект предназначен для Android версии 11 (API версии 30) или более поздней версии, необходимо обновить приложение AndroidManifest.xml для соответствия требованиям к видимости пакета Android. Откройте TodoApp.Uno.Mobile/Android/AndroidManifest.xml и добавьте следующие queries/intent узлы в manifest узел:

<manifest>
  ...
  <queries>
    <intent>
      <action android:name="android.support.customtabs.action.CustomTabsService" />
    </intent>
  </queries>
</manifest>

Измените MainActivity.Android.cs класс; добавьте OnActivityResult метод:

using Android.Views;
using Microsoft.Identity.Client;

namespace TodoApp.Uno.Droid
{
    [Activity(
        MainLauncher = true,
        ConfigurationChanges = global::Uno.UI.ActivityHelper.AllConfigChanges,
        WindowSoftInputMode = SoftInput.AdjustNothing | SoftInput.StateHidden
    )]
    public class MainActivity : Microsoft.UI.Xaml.ApplicationActivity
    {
        protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
        }
    }
}

Когда Android требует проверки подлинности, он получает клиент удостоверений, а затем переключается на внутреннее действие, которое открывает системный браузер. После завершения проверки подлинности системный браузер перенаправляется на определенный URL-адрес перенаправления (msal{client-id}://auth). Перехватывает MasalActvity URL-адрес перенаправления, который затем переключается обратно на основное действие путем вызова OnActivityResult(). Метод OnActivityResult() вызывает вспомогательное средство проверки подлинности MSAL для завершения транзакции.

Тестирование приложения Android

Задайте TodoApp.Uno.Mobile в качестве запускаемого проекта, выберите эмулятор Android в качестве целевого объекта, а затем нажмите клавишу F5 , чтобы создать и запустить приложение. При запуске приложения вам будет предложено войти в приложение. При первом запуске вам также предлагается предоставить согласие на приложение. После завершения проверки подлинности приложение запускается как обычное.

Следующие шаги

Затем настройте приложение для работы в автономном режиме, реализуя автономное хранилище.

Дополнительные материалы