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


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

Заметка

Этот продукт отставлен. Сведения о замене проектов с помощью .NET 8 или более поздней версии см. вбиблиотеке Community Toolkit Datasync.

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

Кончик

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

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

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

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

  • Зарегистрируйте приложение с помощью идентификатора Microsoft Entra.
  • Добавьте проверку подлинности в проект серверной части 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 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 в поле поиска.

    снимок экрана: добавление M S A L NuGet в 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, который указывает, что требуется проверка подлинности.

снимок экрана браузера с ошибкой.

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

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

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

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

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

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

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

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

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

    снимок экрана регистрации области на портале Azure.

  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. Перейдите на вкладку Обзор.

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

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

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

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

    снимок экрана: выбор nuGet uno MSAL в Visual Studio.

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

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

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

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

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

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

    снимок экрана: выбор MSAL NuGet в Visual Studio.

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

Заметка

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

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

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

Откройте проект TodoApp.Data и измените файл Constants.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>"
      };
  }

Замените идентификатором собственного клиентского приложения при регистрации клиентского приложения в идентификаторе Microsoft Entra ID, а области веб-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, чтобы создать и запустить приложение. При запуске приложения вам будет предложено войти в приложение. При первом запуске вам также предлагается предоставить согласие на приложение. После завершения проверки подлинности приложение запускается как обычное.

Дальнейшие действия

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

Дальнейшее чтение