Добавление проверки подлинности в приложение MAUI .NET
Заметка
Этот продукт отставлен. Сведения о замене проектов с помощью .NET 8 или более поздней версии см. вбиблиотеке
В этом руководстве описано, как добавить проверку подлинности Майкрософт в проект TodoApp с помощью идентификатора Microsoft Entra. Перед выполнением этого руководства убедитесь, что вы создали проект и развернули серверную.
Кончик
Хотя мы используем идентификатор Microsoft Entra для проверки подлинности, вы можете использовать любую библиотеку проверки подлинности, которую вы хотите использовать с мобильными приложениями Azure.
Добавление проверки подлинности в серверную службу
Серверная служба — это стандартная служба ASP.NET 6. В любом руководстве показано, как включить проверку подлинности для службы ASP.NET 6, которая работает с мобильными приложениями Azure.
Чтобы включить проверку подлинности Microsoft Entra для серверной службы, необходимо:
- Зарегистрируйте приложение с помощью идентификатора Microsoft Entra.
- Добавьте проверку подлинности в проект серверной части ASP.NET 6.
Регистрация приложения
Сначала зарегистрируйте веб-API в клиенте Microsoft Entra и добавьте область, выполнив следующие действия:
Если у вас есть доступ к нескольким клиентам, используйте каталоги и подписки, фильтр в верхнем меню, чтобы переключиться на клиент, в котором требуется зарегистрировать приложение.
Найдите и выберите идентификатор Microsoft Entra ID.
В разделе Управлениевыберите регистрации приложений>новой регистрации.
имя : введите имя приложения; например,краткого руководства todoApp. Пользователи приложения увидят это имя. Вы можете изменить его позже. - Поддерживаемые типы учетных записей: учетные записи в любом каталоге организации (любой каталог Microsoft Entra — Multitenant) и личных учетных записей Майкрософт (например, Skype, Xbox)
Выберите Зарегистрировать.
В разделе Управлениевыберите Предоставить API>Добавить область.
Для URI идентификатора приложенияпримите значение по умолчанию, выбрав Сохранить и продолжить.
Введите следующие сведения:
- имени области
: - Кто может согласиться?: администраторы и пользователи
- отображаемое имя согласия администратора
: - описания согласия администратора
: -
отображаемое имя согласия пользователя:
Access TodoApp
-
описание согласия пользователя:
Allow the app to access TodoApp on your behalf.
- состояние: включено
- имени области
Выберите Добавить область, чтобы завершить добавление области.
Обратите внимание на значение области, аналогичной
api://<client-id>/access_as_user
(называемой областью области веб-API). Вам нужна область при настройке клиента.Выберите Обзор.
Обратите внимание на идентификатор приложения
(клиента) в разделе Essentials (идентификатор приложения веб-API). Это значение необходимо для настройки серверной службы.
Откройте Visual Studio и выберите проект TodoAppService.NET6
.
Щелкните правой кнопкой мыши проект
TodoAppService.NET6
, а затем выберите Управление пакетами NuGet....На новой вкладке выберите Обзор, а затем введите Microsoft.Identity.Web в поле поиска.
Выберите пакет
Microsoft.Identity.Web
, а затем нажмите Установить.Следуйте инструкциям, чтобы завершить установку пакета.
Откройте
Program.cs
. Добавьте следующее в список операторовusing
:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
- Добавьте следующий код непосредственно над вызовом
builder.Services.AddDbContext()
:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
- Добавьте следующий код непосредственно над вызовом
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();
- Измените
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))
{
}
}
}
- Измените
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 еще раз:
- Щелкните правой кнопкой мыши проект
TodoAppService.NET6
, а затем выберите Опубликовать.... - Нажмите кнопку Опубликовать в правом верхнем углу вкладки.
Откройте браузер для https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0
. Обратите внимание, что служба теперь возвращает ответ 401
, который указывает, что требуется проверка подлинности.
Регистрация приложения в службе удостоверений
Платформа синхронизации данных Майкрософт имеет встроенную поддержку для любого поставщика проверки подлинности, использующего веб-токен Json (JWT) в заголовке транзакции HTTP. Это приложение использует библиотеку проверки подлинности Майкрософт (MSAL) для запроса такого маркера и авторизации пользователя, выполнившего вход в серверную службу.
Настройка собственного клиентского приложения
Вы можете зарегистрировать собственные клиенты, чтобы разрешить проверку подлинности в веб-API, размещенных в приложении, с помощью клиентской библиотеки, например библиотеки удостоверений Майкрософт (MSAL).
На портале Azureвыберите Идентификатор Microsoft Entra ID>регистрации приложений>новой регистрации.
На странице регистрация приложения:
- Введите имени
для регистрации приложения. Вы можете использовать имя native-quickstart
, чтобы отличить его от имени, используемого серверной службой. - Выберите учетные записи в любом каталоге организации (любой каталог Microsoft Entra — Multitenant) и личных учетных записей Майкрософт (например, Skype, Xbox).
- В URI перенаправления:
- Выберите общедоступный клиент (мобильный & настольный компьютер)
- Введите URL-адрес
quickstart://auth
- Введите имени
Выберите Зарегистрировать.
Выберите разрешения API>Добавить разрешение>мои API.
Выберите регистрацию приложения, созданную ранее для серверной службы. Если вы не видите регистрацию приложения, убедитесь, что вы добавили область access_as_user.
В разделе Выбор разрешенийвыберите access_as_user, а затем выберите Добавить разрешения.
Выберите >мобильных и классических приложений проверки подлинности.
Установите флажок рядом с
https://login.microsoftonline.com/common/oauth2/nativeclient
.Установите флажок рядом с
msal{client-id}://auth
(заменяя{client-id}
идентификатором приложения).Выберите добавить URI, а затем добавьте
http://localhost
в поле для дополнительных URI.Выберите Сохранить в нижней части страницы.
Выберите Обзор. Запишите идентификатор приложения
(клиента), который называется идентификатором собственного клиентского приложения ), так как это необходимо для настройки мобильного приложения.
Мы определили три URL-адреса перенаправления:
-
http://localhost
используется приложениями WPF. -
https://login.microsoftonline.com/common/oauth2/nativeclient
используется приложениями UWP. -
msal{client-id}://auth
используется мобильными приложениями (Android и iOS).
Добавление клиента удостоверений Майкрософт в приложение
Откройте решение TodoApp.sln
в Visual Studio и задайте проект TodoApp.MAUI
в качестве запускаемого проекта. Добавьте библиотеки удостоверений Майкрософт (MSAL)
Добавьте библиотеки удостоверений Майкрософт (MSAL)
Щелкните проект правой кнопкой мыши, а затем выберите Управление пакетами NuGet....
Перейдите на вкладку Обзор.
Введите
Microsoft.Identity.Client
в поле поиска, а затем нажмите клавишу ВВОД.Выберите результат
Microsoft.Identity.Client
, а затем щелкните Установить.Примите лицензионное соглашение, чтобы продолжить установку.
Добавьте собственный идентификатор клиента и область серверной части в конфигурацию.
Откройте проект 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 Microsoft Entra ID
/// </summary>
public static string ApplicationId = "<client-id>";
/// <summary>
/// The list of scopes to request
/// </summary>
public static string[] Scopes = new[]
{
"<scope>"
};
}
Замените
Откройте класс MainPage.xaml.cs
в проекте TodoApp.MAUI
. Добавьте следующие операторы using
:
using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
В классе MainPage
добавьте новое свойство:
public IPublicClientApplication IdentityClient { get; set; }
Настройте конструктор для чтения:
public MainPage()
{
InitializeComponent();
TodoService = new RemoteTodoService(GetAuthenticationToken);
viewModel = new MainViewModel(this, TodoService);
BindingContext = viewModel;
}
Добавьте метод GetAuthenticationToken
в класс:
public async Task<AuthenticationToken> GetAuthenticationToken()
{
if (IdentityClient == null)
{
#if ANDROID
IdentityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithRedirectUri($"msal{Constants.ApplicationId}://auth")
.WithParentActivityOrWindow(() => Platform.CurrentActivity)
.Build();
#elif IOS
IdentityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithIosKeychainSecurityGroup("com.microsoft.adalcache")
.WithRedirectUri($"msal{Constants.ApplicationId}://auth")
.Build();
#else
IdentityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
.Build();
#endif
}
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)
{
Debug.WriteLine($"MSAL Silent Error: {ex.Message}");
}
if (tryInteractiveLogin)
{
try
{
result = await IdentityClient
.AcquireTokenInteractive(Constants.Scopes)
.ExecuteAsync();
}
catch (Exception ex)
{
Debug.WriteLine($"MSAL Interactive Error: {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
создается с данными, необходимыми для авторизации каждого запроса. Если нет, вместо этого создается неправильный маркер с истекшим сроком действия.
Мы можем добавить любые параметры для конкретной платформы, используя области #if
с описателями платформы. Например, Android требует указать родительское действие, которое передается на вызывающую страницу.
Настройка приложения Android для проверки подлинности
Создайте новый класс Platforms\Android\MsalActivity.cs
со следующим кодом:
using Android.App;
using Android.Content;
using Microsoft.Identity.Client;
namespace TodoApp.MAUI
{
[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. Откройте Platforms/Android/AndroidManifest.xml
и добавьте следующие узлы queries/intent
на узел manifest
:
<manifest>
...
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest>
Откройте MauiProgram.cs
. Включите следующие using
инструкции в верхней части файла:
using Microsoft.Identity.Client;
Обновите построитель до следующего кода:
builder
.UseMauiApp<App>()
.ConfigureLifecycleEvents(events =>
{
#if ANDROID
events.AddAndroid(platform =>
{
platform.OnActivityResult((activity, rc, result, data) =>
{
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(rc, result, data);
});
});
#endif
})
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
Если вы выполняете этот шаг после обновления приложения для iOS, добавьте код, указанный #if ANDROID
(включая #if
и #endif
). Компилятор выбирает правильный фрагмент кода на основе скомпилированной платформы. Этот код можно поместить либо до, либо после существующего блока для iOS.
Когда Android требует проверки подлинности, он получает клиент удостоверений, а затем переключается на внутреннее действие, которое открывает системный браузер. После завершения проверки подлинности системный браузер перенаправляется на определенный URL-адрес перенаправления (msal{client-id}://auth
).
MsalActivity
перехватывает URL-адрес перенаправления, который затем переключается обратно на основное действие путем вызова OnActivityResult()
. Метод OnActivityResult()
вызывает вспомогательное средство проверки подлинности MSAL для завершения транзакции.
Тестирование приложения Android
Задайте TodoApp.MAUI
в качестве запускаемого проекта, выберите эмулятор Android в качестве целевого объекта, а затем нажмите F5, чтобы создать и запустить приложение. При запуске приложения вам будет предложено войти в приложение. При первом запуске вам будет предложено предоставить согласие на приложение. После завершения проверки подлинности приложение запускается как обычное.
Тестирование приложения Windows
Задайте TodoApp.MAUI
в качестве запускаемого проекта, выберите windows Machine в качестве целевого объекта, а затем нажмите клавишу F5, чтобы создать и запустить приложение. При запуске приложения вам будет предложено войти в приложение. При первом запуске вам будет предложено предоставить согласие на приложение. После завершения проверки подлинности приложение запускается как обычное.
Дальнейшие действия
Затем настройте приложение для работы в автономном режиме, реализации автономного хранилища.