Adición de autenticación a la aplicación MAUI de .NET
Nota
Este producto se retira. Para obtener un reemplazo de proyectos con .NET 8 o posterior, consulte la biblioteca datasync de Community Toolkit.
En este tutorial, agregará la autenticación de Microsoft al proyecto TodoApp mediante el identificador de Microsoft Entra. Antes de completar este tutorial, asegúrese de que ha creado el proyecto e implementado elback-end.
Propina
Aunque usamos microsoft Entra ID para la autenticación, puede usar cualquier biblioteca de autenticación que desee con Azure Mobile Apps.
Adición de autenticación al servicio back-end
El servicio back-end es un servicio estándar ASP.NET 6. Cualquier tutorial que muestre cómo habilitar la autenticación para un servicio ASP.NET 6 funciona con Azure Mobile Apps.
Para habilitar la autenticación de Microsoft Entra para el servicio back-end, debe:
- Registre una aplicación con el identificador de Entra de Microsoft.
- Agregue la comprobación de autenticación al proyecto de back-end de ASP.NET 6.
Registro de la aplicación
En primer lugar, registre la API web en el inquilino de Microsoft Entra y agregue un ámbito siguiendo estos pasos:
Inicie sesión en Azure Portal.
Si tiene acceso a varios inquilinos, use el Directorios y suscripciones filtrar en el menú superior para cambiar al inquilino en el que desea registrar la aplicación.
Busque y seleccione id. de Microsoft Entra.
En Administrar, seleccione Registros de aplicaciones>Nuevo registro.
- Nombre: escriba un nombre para la aplicación; por ejemplo, inicio rápido de TodoApp. Los usuarios de la aplicación verán este nombre. Puede cambiarlo más adelante.
- tipos de cuenta admitidos: cuentas de en cualquier directorio organizativo (cualquier directorio de Microsoft Entra: multiinquilino) y cuentas microsoft personales (por ejemplo, Skype, Xbox)
Seleccione Registrar.
En Administrar, seleccione Exponer una API>Agregar un ámbito.
Para URI de identificador de aplicación, acepte el valor predeterminado seleccionando Guardar y continuar.
Escriba los detalles siguientes:
-
Nombre de ámbito:
access_as_user
- ¿Quién puede dar su consentimiento?: administradores y usuarios de
-
nombre para mostrar del consentimiento del administrador:
Access TodoApp
-
Descripción del consentimiento del administrador:
Allows the app to access TodoApp as the signed-in user.
-
Nombre para mostrar del consentimiento del usuario:
Access TodoApp
-
Descripción del consentimiento del usuario:
Allow the app to access TodoApp on your behalf.
- state: habilitado
-
Nombre de ámbito:
Seleccione Agregar de ámbito para completar la adición del ámbito.
Tenga en cuenta el valor del ámbito, similar a
api://<client-id>/access_as_user
(denominado ámbito de api web de ). Necesita el ámbito al configurar el cliente.Seleccione Información general.
Anote la de id. de aplicación (cliente) de
en la sección Essentials (denominada id. de aplicación de API web ). Necesita este valor para configurar el servicio back-end.
Abra Visual Studio y seleccione el proyecto de TodoAppService.NET6
.
Haga clic con el botón derecho en el proyecto de
TodoAppService.NET6
y seleccione Administrar paquetes NuGet....En la nueva pestaña, seleccione Examinary escriba Microsoft.Identity.Web en el cuadro de búsqueda.
Seleccione el paquete de
Microsoft.Identity.Web
y presione Instalar.Siga las indicaciones para completar la instalación del paquete.
Abra
Program.cs
. Agregue lo siguiente a la lista de instruccionesusing
:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
- Agregue el código siguiente directamente encima de la llamada a
builder.Services.AddDbContext()
:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
- Agregue el código siguiente directamente encima de la llamada a
app.MapControllers()
:
app.UseAuthentication();
app.UseAuthorization();
La Program.cs
debería tener este aspecto:
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();
- Edite el
Controllers\TodoItemController.cs
. Agregue un atributo[Authorize]
a la clase . La clase debe tener este aspecto:
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))
{
}
}
}
- Edite el
appsettings.json
. Agregue el siguiente bloque:
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"ClientId": "<client-id>",
"TenantId": "common"
},
Reemplace el <client-id>
por el identificador de aplicación de API web de que registró anteriormente. Una vez completado, debería tener este aspecto:
{
"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": "*"
}
Vuelva a publicar el servicio en Azure:
- Haga clic con el botón derecho en el proyecto de
TodoAppService.NET6
y seleccione Publicar.... - Seleccione el botón Publicar en la esquina superior derecha de la pestaña.
Abra un explorador para https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0
. Tenga en cuenta que el servicio ahora devuelve una respuesta 401
, lo que indica que se requiere autenticación.
Registro de la aplicación con el servicio de identidad
Microsoft Data Sync Framework tiene compatibilidad integrada con cualquier proveedor de autenticación que use un token web json (JWT) dentro de un encabezado de la transacción HTTP. Esta aplicación usa el de la biblioteca de autenticación de Microsoft (MSAL) de
Configuración de una aplicación cliente nativa
Puede registrar clientes nativos para permitir la autenticación en las API web hospedadas en la aplicación mediante una biblioteca cliente, como la Biblioteca de identidades de Microsoft (MSAL).
En azure Portal, seleccione Microsoft Entra ID>Registros de aplicaciones>Nuevo registro.
En la página Registrar una aplicación:
- escriba un Nombre para el registro de la aplicación. Es posible que quiera usar el nombre
native-quickstart
para distinguirlo del que usa el servicio back-end. - Seleccione Cuentas en cualquier directorio organizativo (cualquier directorio microsoft Entra - Multiinquilino) y cuentas microsoft personales (por ejemplo, Skype, Xbox).
- En URI de redirección:
- Seleccione cliente público (escritorio de & móvil)
- Escriba la dirección URL
quickstart://auth
- escriba un Nombre para el registro de la aplicación. Es posible que quiera usar el nombre
Seleccione Registrar.
Seleccione permisos de API>Agregar un permiso>Mis API.
Seleccione el registro de aplicaciones que creó anteriormente para el servicio back-end. Si no ve el registro de la aplicación, asegúrese de agregar el ámbito de access_as_user.
En Seleccionar permisos, seleccione access_as_usery, a continuación, seleccione Agregar permisos.
Seleccione Autenticación>aplicaciones móviles y de escritorio.
Active la casilla situada junto a
https://login.microsoftonline.com/common/oauth2/nativeclient
.Active la casilla situada junto a
msal{client-id}://auth
(reemplazando{client-id}
por el identificador de aplicación).Seleccione Agregar URIy agregue
http://localhost
en el campo para URI adicionales.Seleccione Guardar en la parte inferior de la página.
Seleccione Información general. Anote la de id. de aplicación (cliente) de
(denominada id. de aplicación de Native Client ) según sea necesario para configurar la aplicación móvil.
Hemos definido tres direcciones URL de redireccionamiento:
- las aplicaciones de WPF usan
http://localhost
. - las aplicaciones para UWP usan
https://login.microsoftonline.com/common/oauth2/nativeclient
. - las aplicaciones móviles (Android e iOS) usan
msal{client-id}://auth
.
Adición de Microsoft Identity Client a la aplicación
Abra la solución TodoApp.sln
en Visual Studio y establezca el proyecto de TodoApp.MAUI
como proyecto de inicio. Agregue el biblioteca de identidades de Microsoft (MSAL)
Agregue el
Haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet....
Seleccione la pestaña Examinar
. Escriba
Microsoft.Identity.Client
en el cuadro de búsqueda y presione Entrar.Seleccione el resultado
Microsoft.Identity.Client
y haga clic en Instalar.Acepte el contrato de licencia para continuar con la instalación.
Agregue el identificador de cliente nativo y el ámbito de back-end a la configuración.
Abra el proyecto TodoApp.Data
y edite el archivo Constants.cs
. Agregue constantes para ApplicationId
y 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>"
};
}
Reemplace el <client-id>
por el id. de aplicación de Native Client que recibió al registrar la aplicación cliente en el id. de Microsoft Entra y el <scope>
por el ámbito de la API web de que copió al usar Exponer una API al registrar la aplicación de servicio.
Abra la clase MainPage.xaml.cs
en el proyecto de TodoApp.MAUI
. Agregue las siguientes instrucciones using
:
using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
En la clase MainPage
, agregue una nueva propiedad:
public IPublicClientApplication IdentityClient { get; set; }
Ajuste el constructor para leer:
public MainPage()
{
InitializeComponent();
TodoService = new RemoteTodoService(GetAuthenticationToken);
viewModel = new MainViewModel(this, TodoService);
BindingContext = viewModel;
}
Agregue el método GetAuthenticationToken
a la clase :
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 ?? ""
};
}
El método GetAuthenticationToken()
funciona con la Biblioteca de identidades de Microsoft (MSAL) para obtener un token de acceso adecuado para autorizar al usuario que ha iniciado sesión en el servicio back-end. A continuación, esta función se pasa al RemoteTodoService
para crear el cliente. Si la autenticación se realiza correctamente, el AuthenticationToken
se genera con los datos necesarios para autorizar cada solicitud. Si no es así, se genera un token incorrecto expirado en su lugar.
Podemos agregar cualquier opción específica de la plataforma mediante las áreas de #if
con un especificador de plataforma. Por ejemplo, Android requiere que especifiquemos la actividad primaria, que se pasa desde la página de llamada.
Configuración de la aplicación Android para la autenticación
Cree una nueva clase Platforms\Android\MsalActivity.cs
con el código siguiente:
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
{
}
}
Reemplace {client-id}
por el identificador de aplicación del cliente nativo (que es el mismo que Constants.ApplicationId
).
Si el proyecto tiene como destino Android versión 11 (versión 30 de API) o posterior, debe actualizar el AndroidManifest.xml
para cumplir los requisitos de visibilidad de paquetes android . Abra Platforms/Android/AndroidManifest.xml
y agregue los siguientes nodos queries/intent
al nodo manifest
:
<manifest>
...
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest>
Abra MauiProgram.cs
. Incluya las siguientes instrucciones using
en la parte superior del archivo:
using Microsoft.Identity.Client;
Actualice el generador al código siguiente:
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");
});
Si va a realizar este paso después de actualizar la aplicación para iOS, agregue el código designado por el #if ANDROID
(incluido el #if
y #endif
). El compilador elige el fragmento de código correcto en función de la plataforma que se está compilando. Este código se puede colocar antes o después del bloque existente para iOS.
Cuando Android requiere autenticación, obtiene un cliente de identidad y, a continuación, cambia a una actividad interna que abre el explorador del sistema. Una vez completada la autenticación, el explorador del sistema redirige a la dirección URL de redireccionamiento definida (msal{client-id}://auth
). El MsalActivity
intercepta la dirección URL de redireccionamiento, que luego vuelve a la actividad principal llamando a OnActivityResult()
. El método OnActivityResult()
llama al asistente de autenticación msal para completar la transacción.
Prueba de la aplicación Android
Establezca TodoApp.MAUI
como proyecto de inicio, seleccione un emulador de Android como destino y presione F5 para compilar y ejecutar la aplicación. Cuando se inicie la aplicación, se le pedirá que inicie sesión en la aplicación. En la primera ejecución, se le pide que dé su consentimiento a la aplicación. Una vez completada la autenticación, la aplicación se ejecuta como normal.
Prueba de la aplicación de Windows
Establezca TodoApp.MAUI
como proyecto de inicio, seleccione máquina Windows como destino y presione F5 para compilar y ejecutar la aplicación. Cuando se inicie la aplicación, se le pedirá que inicie sesión en la aplicación. En la primera ejecución, se le pide que dé su consentimiento a la aplicación. Una vez completada la autenticación, la aplicación se ejecuta como normal.
Pasos siguientes
A continuación, configure la aplicación para que funcione sin conexión implementando un almacén sin conexión.