Compartir a través de


Agregar autenticación a la aplicación de Windows (WPF)

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:

  1. Inicie sesión en Azure Portal.

  2. 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.

  3. Busque y seleccione id. de Microsoft Entra.

  4. 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)
  5. Seleccione Registrar.

  6. En Administrar, seleccione Exponer una API>Agregar un ámbito.

  7. Para URI de identificador de aplicación, acepte el valor predeterminado seleccionando Guardar y continuar.

  8. 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
  9. Seleccione Agregar de ámbito para completar la adición del ámbito.

  10. 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.

  11. Seleccione Información general.

  12. 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.

  1. Haga clic con el botón derecho en el proyecto de TodoAppService.NET6 y seleccione Administrar paquetes NuGet....

  2. En la nueva pestaña, seleccione Examinary escriba Microsoft.Identity.Web en el cuadro de búsqueda.

    Captura de pantalla de cómo agregar M S A L NuGet en Visual Studio.

  3. Seleccione el paquete de Microsoft.Identity.Web y presione Instalar.

  4. Siga las indicaciones para completar la instalación del paquete.

  5. Abra Program.cs. Agregue lo siguiente a la lista de instrucciones using:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
  1. 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();
  1. 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();
  1. 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))
    {
    }
  }
}
  1. 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:

  1. Haga clic con el botón derecho en el proyecto de TodoAppService.NET6 y seleccione Publicar....
  2. 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.

Captura de pantalla del explorador que muestra un error.

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 para solicitar este token y autorizar al usuario que ha iniciado sesión en el servicio back-end.

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).

  1. En azure Portal, seleccione Microsoft Entra ID>Registros de aplicaciones>Nuevo registro.

  2. 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
  3. Seleccione Registrar.

  4. Seleccione permisos de API>Agregar un permiso>Mis API.

  5. 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.

    Captura de pantalla del registro de ámbito en Azure Portal.

  6. En Seleccionar permisos, seleccione access_as_usery, a continuación, seleccione Agregar permisos.

  7. Seleccione Autenticación>aplicaciones móviles y de escritorio.

  8. Active la casilla situada junto a https://login.microsoftonline.com/common/oauth2/nativeclient.

  9. Active la casilla situada junto a msal{client-id}://auth (reemplazando {client-id} por el identificador de aplicación).

  10. Seleccione Agregar URIy agregue http://localhost en el campo para URI adicionales.

  11. Seleccione Guardar en la parte inferior de la página.

  12. 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.WPFcomo proyecto de inicio. Agregue el biblioteca de identidades de Microsoft (MSAL) al proyecto de :

Agregue el Biblioteca de identidades de Microsoft (MSAL) al proyecto de plataforma:

  1. Haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet....

  2. Seleccione la pestaña Examinar .

  3. Escriba Microsoft.Identity.Client en el cuadro de búsqueda y presione Entrar.

  4. Seleccione el resultado Microsoft.Identity.Client y haga clic en Instalar.

    Captura de pantalla de la selección de NuGet de MSAL en Visual Studio.

  5. 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 el archivo App.xaml.cs en el proyecto de TodoApp.WPF.

Agregue las siguientes instrucciones using en la parte superior del archivo:

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

Quite la propiedad TodoService y reemplácela por el código siguiente:

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 ?? ""
    };
}

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.

Prueba de la aplicación

Debería poder presionar F5 para ejecutar la aplicación. Cuando se ejecuta la aplicación, se abre un explorador para solicitar la autenticación. La primera vez que se ejecuta la aplicación, se le pide que dé su consentimiento al acceso:

Captura de pantalla de la solicitud de consentimiento de Microsoft Entra.

Presione para continuar con la aplicación.

Pasos siguientes

A continuación, configure la aplicación para que funcione sin conexión implementando un almacén sin conexión.

Lectura adicional