Autenticación de usuarios con Azure Active Directory B2C
Azure Active Directory B2C proporciona administración de identidades en la nube para aplicaciones web y móviles orientadas al consumidor. En este artículo se muestra cómo usar Azure Active Directory B2C para integrar la administración de identidades en una aplicación móvil con la biblioteca de autenticación de Microsoft.
Información general
Azure Active Directory B2C (ADB2C) es un servicio de administración de identidades para aplicaciones orientadas al consumidor. Permite a los usuarios iniciar sesión en la aplicación con sus cuentas de redes sociales existentes o credenciales personalizadas, como correo electrónico, nombre de usuario y contraseña. Las cuentas de credenciales personalizadas se conocen como cuentas locales.
El proceso de integración de Azure Active Directory servicio de administración de identidades B2C en una aplicación móvil es el siguiente:
- Crear un inquilino de Azure Active Directory B2C.
- Registre la aplicación móvil con el Azure Active Directory de B2C.
- Cree directivas para el registro y el inicio de sesión, y olvide los flujos de usuario de contraseña.
- Use la Biblioteca de autenticación de Microsoft (MSAL) para iniciar un flujo de trabajo de autenticación con su Azure Active Directory B2C.
Nota:
Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.
Azure Active Directory B2C admite varios proveedores de identidades, como Microsoft, GitHub, Facebook, Twitter, etc. Para más información sobre las Azure Active Directory B2C, consulte la documentación Azure Active Directory B2C.
La biblioteca de autenticación de Microsoft admite varias plataformas y arquitecturas de aplicaciones. Para obtener información sobre las funcionalidades de MSAL, vea Biblioteca de autenticación de Microsoft GitHub.
Configuración de un Azure Active Directory B2C
Para ejecutar el proyecto de ejemplo, debe crear un Azure Active Directory de B2C. Para obtener más información, consulte Creación de Azure Active Directory inquilino de B2C en el Azure Portal.
Una vez creado un inquilino, necesitará el nombre del inquilino y el identificador del inquilino para configurar la aplicación móvil. El identificador de inquilino y el nombre se definen mediante el dominio generado al crear la dirección URL del inquilino. Si la dirección URL de inquilino generada https://contoso20190410tenant.onmicrosoft.com/ es el identificador https://contoso20190410tenant.onmicrosoft.com/ inquilino es y el nombre contoso20190410tenant.onmicrosoft.com del contoso20190410tenant.onmicrosoft.com es contoso20190410tenant . Busque el dominio de inquilino en la Azure Portal haga clic en el filtro de directorio y suscripción en el menú superior. En la captura de pantalla siguiente se muestra el botón de filtro de directorio y suscripción de Azure y el dominio de inquilino:
En el proyecto de ejemplo, edite el archivo Constants.cs para establecer los campos y tenantId . El código siguiente muestra cómo se deben establecer estos valores si el dominio de inquilino es , reemplace estos valores https://contoso20190410tenant.onmicrosoft.com/ por valores del portal:
public static class Constants
{
static readonly string tenantName = "contoso20190410tenant";
static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
...
}
Registro de la aplicación móvil con Azure Active Directory B2C
Una aplicación móvil debe registrarse con el inquilino para poder conectarse y autenticar a los usuarios. El proceso de registro asigna un identificador de aplicación único a la aplicación y una dirección URL de redireccionamiento que dirige las respuestas a la aplicación después de la autenticación. Para más información, consulte Azure Active Directory B2C: Registrar la aplicación. Deberá conocer el identificador de aplicación asignado a la aplicación, que aparece después del nombre de la aplicación en la vista de propiedades. En la captura de pantalla siguiente se muestra dónde encontrar el identificador de aplicación:
La biblioteca de autenticación de Microsoft espera que la dirección URL de redireccionamiento de la aplicación sea el identificador de la aplicación con el prefijo "msal" y, después, un punto de conexión denominado "auth". Si el identificador de la aplicación es "1234abcd", la dirección URL completa debe ser msal1234abcd://auth . Asegúrese de que la aplicación ha habilitado la configuración de Cliente nativo y cree un URI de redireccionamiento personalizado con el identificador de aplicación, como se muestra en la captura de pantalla siguiente:

La dirección URL se usará más adelante en android ApplicationManifest.xml iOS Info.plist.
En el proyecto de ejemplo, edite el archivo Constants.cs para establecer el campo en el identificador de aplicación. El código siguiente muestra cómo se debe establecer este valor si el identificador de aplicación es 1234abcd :
public static class Constants
{
static readonly string tenantName = "contoso20190410tenant";
static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
static readonly string clientId = "1234abcd";
...
}
Crear directivas de registro e inicio de sesión, y olvidar las directivas de contraseña
Una directiva es una experiencia por la que pasan los usuarios para completar una tarea, como crear una cuenta o restablecer una contraseña. Una directiva también especifica el contenido de los tokens que recibe la aplicación cuando el usuario vuelve de la experiencia. Debe configurar directivas para el registro e inicio de sesión de la cuenta, y restablecer la contraseña. Azure tiene directivas integradas que simplifican la creación de directivas comunes. Para obtener más información, vea Azure Active Directory B2C: Directivas integradas.
Cuando haya completado la configuración de directivas, debe tener dos directivas en la vista Flujos de usuario (directivas) en el Azure Portal. En la captura de pantalla siguiente se muestran dos directivas configuradas en el Azure Portal:

En el proyecto de ejemplo, edite el archivo Constants.cs para establecer los campos y para reflejar los nombres que eligió durante la configuración de la policyPassword directiva:
public static class Constants
{
static readonly string tenantName = "contoso20190410tenant";
static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
static readonly string clientId = "1234abcd";
static readonly string policySignin = "B2C_1_signupsignin1";
static readonly string policyPassword = "B2C_1_passwordreset";
...
}
Uso de la biblioteca de autenticación de Microsoft (MSAL) para la autenticación
El paquete de NuGet biblioteca de autenticación de Microsoft (MSAL) debe agregarse al proyecto compartido .NET Standard y a los proyectos de plataforma de una Xamarin.Forms solución. MSAL incluye una PublicClientApplicationBuilder clase que construye un objeto que se adhiere a la interfaz IPublicClientApplication . MSAL utiliza With cláusulas para proporcionar parámetros adicionales al constructor y a los métodos de autenticación.
En el proyecto de ejemplo, el código subyacente de App.xaml define las propiedades estáticas denominadas y , y crea instancias del UIParent objeto en el AuthenticationClient constructor. La WithIosKeychainSecurityGroup cláusula proporciona un nombre de grupo de seguridad para aplicaciones iOS. La WithB2CAuthority cláusula proporciona la directiva WithB2CAuthorityo predeterminada que se usará para autenticar a los usuarios. La cláusula indica a la instancia de Azure Notification Hubs uri de redirección que se usará WithRedirectUri si se especifican varios URI. En el ejemplo siguiente se muestra cómo crear una instancia de PublicClientApplication :
public partial class App : Application
{
public static IPublicClientApplication AuthenticationClient { get; private set; }
public static object UIParent { get; set; } = null;
public App()
{
InitializeComponent();
AuthenticationClient = PublicClientApplicationBuilder.Create(Constants.ClientId)
.WithIosKeychainSecurityGroup(Constants.IosKeychainSecurityGroups)
.WithB2CAuthority(Constants.AuthoritySignin)
.WithRedirectUri($"msal{Constants.ClientId}://auth")
.Build();
MainPage = new NavigationPage(new LoginPage());
}
...
Nota:
Si la instancia de Azure Notification Hubs solo tiene definido un URI de redirección, la instancia puede funcionar sin especificar el URI de redirección AuthenticationClient con la WithRedirectUri cláusula . Sin embargo, siempre debe especificar este valor en caso de que la configuración de Azure se expanda para admitir otros clientes o métodos de autenticación.
Controlador OnAppearing de eventos del código OnAppearing subyacente a las llamadas para actualizar el token de autenticación para los usuarios AcquireTokenSilentAsync que han iniciado sesión antes. El proceso de autenticación redirige a si LogoutPage se realiza correctamente y no hace nada en caso de error. En el ejemplo siguiente se muestra el proceso de reauauticación silenciosa en OnAppearing :
public partial class LoginPage : ContentPage
{
...
protected override async void OnAppearing()
{
try
{
// Look for existing account
IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();
AuthenticationResult result = await App.AuthenticationClient
.AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
.ExecuteAsync();
await Navigation.PushAsync(new LogoutPage(result));
}
catch
{
// Do nothing - the user isn't logged in
}
base.OnAppearing();
}
...
}
El OnLoginButtonClicked controlador de eventos (que se desencadena cuando se hace clic en el botón Inicio de sesión) llama a AcquireTokenAsync . La biblioteca MSAL abre automáticamente el explorador del dispositivo móvil y navega a la página de inicio de sesión. La dirección URL de inicio de sesión, denominada autoridad, es una combinación del nombre del inquilino y las directivas definidas en el archivo Constants.cs. Si el usuario elige la opción de contraseña olvidada, se devuelve a la aplicación con una excepción, que inicia la experiencia de contraseña olvidada. En el ejemplo siguiente se muestra el proceso de autenticación:
public partial class LoginPage : ContentPage
{
...
async void OnLoginButtonClicked(object sender, EventArgs e)
{
AuthenticationResult result;
try
{
result = await App.AuthenticationClient
.AcquireTokenInteractive(Constants.Scopes)
.WithPrompt(Prompt.SelectAccount)
.WithParentActivityOrWindow(App.UIParent)
.ExecuteAsync();
await Navigation.PushAsync(new LogoutPage(result));
}
catch (MsalException ex)
{
if (ex.Message != null && ex.Message.Contains("AADB2C90118"))
{
result = await OnForgotPassword();
await Navigation.PushAsync(new LogoutPage(result));
}
else if (ex.ErrorCode != "authentication_canceled")
{
await DisplayAlert("An error has occurred", "Exception message: " + ex.Message, "Dismiss");
}
}
}
...
}
El OnForgotPassword método es similar al proceso de inicio de sesión, pero implementa una directiva personalizada. OnForgotPasswordusa una sobrecarga diferente de AcquireTokenAsync , que permite proporcionar una autoridad OnForgotPassword En el ejemplo siguiente se muestra cómo proporcionar una autoridad personalizada al adquirir un token:
public partial class LoginPage : ContentPage
{
...
async Task<AuthenticationResult> OnForgotPassword()
{
try
{
return await App.AuthenticationClient
.AcquireTokenInteractive(Constants.Scopes)
.WithPrompt(Prompt.SelectAccount)
.WithParentActivityOrWindow(App.UIParent)
.WithB2CAuthority(Constants.AuthorityPasswordReset)
.ExecuteAsync();
}
catch (MsalException)
{
// Do nothing - ErrorCode will be displayed in OnLoginButtonClicked
return null;
}
}
}
La última parte de la autenticación es el proceso de cerrar sesión. Se OnLogoutButtonClicked llama al método cuando el usuario presiona el botón cerrar sesión. Recorre en bucle todas las cuentas y garantiza que sus tokens se han invalidado. En el ejemplo siguiente se muestra la implementación de cerrar sesión:
public partial class LogoutPage : ContentPage
{
...
async void OnLogoutButtonClicked(object sender, EventArgs e)
{
IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();
while (accounts.Any())
{
await App.AuthenticationClient.RemoveAsync(accounts.First());
accounts = await App.AuthenticationClient.GetAccountsAsync();
}
await Navigation.PopAsync();
}
}
iOS
En iOS, el esquema de dirección URL personalizado que se registró con Azure Active Directory B2C debe estar registrado en Info.plist. MSAL espera que el esquema de dirección URL se ajuste a un patrón específico, descrito anteriormente en Registro de la aplicación móvil con Azure Active Directory B2C. En la captura de pantalla siguiente se muestra el esquema de dirección URL personalizado en Info.plist.

MSAL también requiere derechos de cadena de claves en iOS, registrados en Entitilements.plist,como se muestra en la captura de pantalla siguiente:

Cuando Azure Active Directory B2C completa la solicitud de autorización, redirige a la dirección URL de redireccionamiento registrada. El esquema de dirección URL personalizada da como resultado que iOS inicie la aplicación móvil y pase la dirección URL como un parámetro de inicio, donde se procesa mediante la invalidación de la clase de la aplicación y devuelve el control de la experiencia a OpenUrlAppDelegate MSAL. La OpenUrl implementación se muestra en el ejemplo de código siguiente:
using Microsoft.Identity.Client;
namespace TodoAzure.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
...
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
return base.OpenUrl(app, url, options);
}
}
}
Android
En Android, el esquema de dirección URL personalizado que se registró con Azure Active Directory B2C debe estar registrado en elAndroidManifest.xml. MSAL espera que el esquema de dirección URL se ajuste a un patrón específico, descrito anteriormente en Registro de la aplicación móvil con Azure Active Directory B2C. En el ejemplo siguiente se muestra el esquema de dirección URL personalizado en elAndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.xamarin.adb2cauthorization">
<uses-sdk android:minSdkVersion="15" />
<application android:label="ADB2CAuthorization">
<activity android:name="microsoft.identity.client.BrowserTabActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- example -->
<!-- <data android:scheme="msalaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" android:host="auth" /> -->
<data android:scheme="INSERT_URI_SCHEME_HERE" android:host="auth" />
</intent-filter>
</activity>"
</application>
</manifest>
La MainActivity clase debe modificarse para proporcionar el objeto UIParent a la aplicación durante la OnCreate llamada. Cuando Azure Active Directory B2C completa la solicitud de autorización, redirige al esquema de dirección URL registrado desde elAndroidManifest.xml. El esquema de URI registrado hace que Android llame al método con la dirección URL como parámetro de inicio, donde el OnActivityResult método lo SetAuthenticationContinuationEventArgs procesa.
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
Forms.Init(this, bundle);
LoadApplication(new App());
App.UIParent = this;
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
}
}
Plataforma universal de Windows
No se requiere ninguna configuración adicional para usar MSAL en la plataforma Windows universal
Ejecución del proyecto
Ejecute la aplicación en un dispositivo virtual o físico. Al pulsar el botón Inicio de sesión, se debe abrir el explorador y navegar a una página donde pueda iniciar sesión o crear una cuenta. Después de completar el proceso de inicio de sesión, debe volver a la página de cierre de sesión de la aplicación. En la captura de pantalla siguiente se muestra la pantalla de inicio de sesión del usuario que se ejecuta en Android e iOS:

Descarga del ejemplo
