Добавление проверки подлинности в приложение Windows (WPF)

В этом руководстве описано, как добавить проверку подлинности Майкрософт в проект 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) для запроса такого маркера и авторизации пользователя, выполнившего вход в серверную службу.

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

Вы можете зарегистрировать собственные клиенты, чтобы разрешить проверку подлинности размещенных в приложении веб-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 и задайте TodoApp.WPFпроект в качестве запускаемого проекта. Добавьте в проект библиотеку удостоверений Майкрософт (MSALTodoApp.WPF):

Добавьте библиотеку удостоверений Майкрософт (MSAL) в проект платформы:

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

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

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

  4. Выберите результат Microsoft.Identity.Client, а затем щелкните Установить.

    Screenshot of selecting the MSAL NuGet in Visual Studio.

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

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

Откройте проект и измените 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 Microsoft Entra ID
      /// </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 при регистрации приложения-службы.

App.xaml.cs Откройте файл в TodoApp.WPF проекте.

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

using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
using System.Linq;

TodoService Удалите свойство и замените его следующим кодом:

static App()
{
    IdentityClient = PublicClientApplicationBuilder.Create(Constants.ApplicationId)
        .WithAuthority(AzureCloudInstance.AzurePublic, "common")
        .WithRedirectUri("http://localhost")
        .Build();
    TodoService = new RemoteTodoService(async () => await GetAuthenticationToken());
}

public static IPublicClientApplication IdentityClient { get; }

public static ITodoService TodoService { get; }

public static async Task<AuthenticationToken> GetAuthenticationToken()
{
    var accounts = await IdentityClient.GetAccountsAsync();
    AuthenticationResult? result = null;
    try
    {
        result = await IdentityClient
            .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
            .ExecuteAsync();
    }
    catch (MsalUiRequiredException)
    {
        result = await IdentityClient
            .AcquireTokenInteractive(Constants.Scopes)
            .ExecuteAsync();
    }
    catch (Exception ex)
    {
        // Display the error text - probably as a pop-up
        Debug.WriteLine($"Error: Authentication failed: {ex.Message}");
    }

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

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

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

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

Screenshot of the Microsoft Entra consent request.

Нажмите кнопку "Да" , чтобы продолжить работу приложения.

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

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

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