Xamarin.Essentials: Web Authenticator

Mit der WebAuthenticator-Klasse können Sie browserbasierte Flows initiieren, die auf einen Rückruf an eine bestimmte URL lauschen, die für die App registriert ist.

Übersicht

Viele Apps erfordern das Hinzufügen einer Benutzerauthentifizierung. Das bedeutet häufig, dass Sie den Benutzern die Anmeldung mit ihren vorhandenen Microsoft-, Facebook- oder Google-Konten und jetzt auch mit der Apple-Anmeldung ermöglichen.

Microsoft Authentication Library (MSAL) bietet eine hervorragende, sofort einsetzbare Lösung zum Hinzufügen einer Authentifizierung zu Ihrer App. Es werden sogar Xamarin-Apps im jeweiligen NuGet-Paket des Clients unterstützt.

Wenn Sie an der Verwendung eines eigenen Webdiensts für die Authentifizierung interessiert sind, können Sie mit WebAuthenticator die clientseitige Funktionalität implementieren.

Gründe für die Verwendung eines Server-Back-Ends

Viele Authentifizierungsanbieter sind dazu übergegangen, nur explizite oder zweibeinige Authentifizierungsflows anzubieten, um höhere Sicherheit zu gewährleisten. Das bedeutet, dass Sie einen geheimen Clientschlüssel vom Anbieter benötigen, um den Authentifizierungsflow durchzufühen. Leider sind mobile Apps nicht besonders gut für die Speicherung geheimer Schlüssel geeignet, und Elemente, die im Code, in Binärdateien oder an anderer Stelle in einer mobilen App gespeichert sind, werden allgemein als unsicher angesehen.

Die bewährte Methode hier ist die Verwendung eines Web-Back-Ends als mittlere Schicht zwischen der mobilen App und dem Authentifizierungsanbieter.

Wichtig

Es wird dringend davon abgeraten, ältere Authentifizierungsbibliotheken und -muster allein auf mobiler Basis zu verwenden, bei denen aufgrund der fehlenden Sicherheit für das Speichern geheimer Clientschlüssel kein Web-Back-End im Authentifizierungsflow genutzt wird.

Erste Schritte

Lesen Sie zum Einstieg in die Verwendung dieser API den Leitfaden mit ersten Schritte für Xamarin.Essentials, um sicherzustellen, dass die Bibliothek ordnungsgemäß installiert und in Ihren Projekten eingerichtet ist.

Für den Zugriff auf die WebAuthenticator-Funktion ist die folgende plattformspezifische Einrichtung erforderlich.

Für Android ist die Einrichtung eines Intent-Filters zur Verarbeitung des Rückruf-URI erforderlich. Dies lässt sich problemlos erreichen, indem Unterklassen der Klasse WebAuthenticatorCallbackActivity erstellt werden:

const string CALLBACK_SCHEME = "myapp";

[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
    Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
    DataScheme = CALLBACK_SCHEME)]
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
}

Wenn die Android-Zielversion des Projekts auf Android 11 (R API 30) festgelegt ist, müssen Sie Ihr Android-Manifest mit Abfragen aktualisieren, die mit den neuen Paketsichtbarkeitsanforderungen verwendet werden.

Öffnen Sie die Datei AndroidManifest.xml im Ordner Eigenschaften, und fügen Sie Folgendes im Knoten Manifest hinzu:

<queries>
    <intent>
        <action android:name="android.support.customtabs.action.CustomTabsService" />
    </intent>
</queries>

Verwenden von WebAuthenticator

Fügen Sie in Ihrer Klasse einen Verweis auf Xamarin.Essentials hinzu:

using Xamarin.Essentials;

Die API besteht hauptsächlich aus einer einzelnen AuthenticateAsync-Methode, die zwei Parameter verwendet: Die URL, die zum Starten des Webbrowser-Flow verwendet werden soll, und der URI, für den der Flow letztendlich einen Rückruf durchführen soll und für dessen Verarbeitung die App registriert ist.

Das Ergebnis ist ein WebAuthenticatorResult, das alle vom Rückruf-URI analysierte Abfrageparameter enthält:

var authResult = await WebAuthenticator.AuthenticateAsync(
        new Uri("https://mysite.com/mobileauth/Microsoft"),
        new Uri("myapp://"));

var accessToken = authResult?.AccessToken;

Die WebAuthenticator-API übernimmt das Starten der URL im Browser und wartet, bis der Rückruf empfangen wird:

Typical Web Authentication Flow

Wenn der/die Benutzer*in den Flow an einem beliebigen Punkt abbricht, wird eine TaskCanceledException ausgelöst.

Private Authentifizierungssitzung

Mit iOS 13 wurde eine kurzlebige Webbrowser-API eingeführt, mit der Entwickler die Authentifizierungssitzung als private Sitzung starten können. Dadurch können Entwickler anfordern, dass zwischen Authentifizierungssitzungen keine freigegebenen Cookies oder Browserdaten verfügbar sind, und jedes Mal eine neue Anmeldesitzung gestartet wird. Dieses Feature ist über das neue WebAuthenticatorOptions-Element verfügbar, das in Xamarin.Essentials 1.7 für iOS eingeführt wurde.

var url = new Uri("https://mysite.com/mobileauth/Microsoft");
var callbackUrl = new Uri("myapp://");
var authResult = await WebAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions
    {
        Url = url,
        CallbackUrl = callbackUrl,
        PrefersEphemeralWebBrowserSession = true
    });

Plattformunterschiede

Sofern verfügbar, werden benutzerdefinierte Registerkarten verwendet, andernfalls wird ein Intent für die URL gestartet.

Apple-Anmeldung

Gemäß den Überprüfungsrichtlinien von Apple muss Ihre App, wenn sie für die Authentifizierung einen Anmeldedienst für soziale Netzwerke verwendet, auch eine Apple-Anmeldung als Option anbieten.

Um Ihren Apps die Apple-Anmeldung hinzuzufügen, müssen Sie zunächst die App für die Verwendung der Apple-Anmeldung konfigurieren.

Unter iOS 13 und höher sollten Sie die AppleSignInAuthenticator.AuthenticateAsync()-Methode aufrufen. Dadurch werden die nativen APIs für die Apple-Anmeldung im Hintergrund verwendet, damit den Benutzern auf diesen Geräten das bestmögliche Nutzungserlebnis geboten wird. Sie können den freigegebenen Code so schreiben, dass die richtige API zur Laufzeit verwendet wird:

var scheme = "..."; // Apple, Microsoft, Google, Facebook, etc.
WebAuthenticatorResult r = null;

if (scheme.Equals("Apple")
    && DeviceInfo.Platform == DevicePlatform.iOS
    && DeviceInfo.Version.Major >= 13)
{
    // Use Native Apple Sign In API's
    r = await AppleSignInAuthenticator.AuthenticateAsync();
}
else
{
    // Web Authentication flow
    var authUrl = new Uri(authenticationUrl + scheme);
    var callbackUrl = new Uri("xamarinessentials://");

    r = await WebAuthenticator.AuthenticateAsync(authUrl, callbackUrl);
}

var authToken = string.Empty;
if (r.Properties.TryGetValue("name", out var name) && !string.IsNullOrEmpty(name))
    authToken += $"Name: {name}{Environment.NewLine}";
if (r.Properties.TryGetValue("email", out var email) && !string.IsNullOrEmpty(email))
    authToken += $"Email: {email}{Environment.NewLine}";

// Note that Apple Sign In has an IdToken and not an AccessToken
authToken += r?.AccessToken ?? r?.IdToken;

Tipp

Bei Nicht-iOS 13-Geräten wird dadurch der Webauthentifizierungsflow gestartet, der auch zum Aktivieren der Apple-Anmeldung auf Ihren Android- und UWP-Geräten verwendet werden kann. Sie können sich auf Ihrem iOS-Simulator bei Ihrem iCloud-Konto anmelden, um die Apple-Anmeldung zu testen.


ASP.NET Core-Server-Back-End

Die WebAuthenticator-API kann mit einem beliebigen Web-Back-End-Dienst verwendet werden. Zur Verwendung mit einer ASP.NET Core-App müssen Sie zunächst die Web-App mit den folgenden Schritten konfigurieren:

  1. Richten Sie die gewünschten externen Anbieter für die Authentifizierung über ein soziales Netzwerk in einer ASP.NET Core-Web-App ein.
  2. Legen Sie das Standardauthentifizierungsschema im Aufruf von .AddAuthentication() auf CookieAuthenticationDefaults.AuthenticationScheme fest.
  3. Verwenden Sie .AddCookie() im Aufruf von .AddAuthentication() in „Startup.cs“.
  4. Alle Anbieter müssen mit .SaveTokens = true; konfiguriert sein.
services.AddAuthentication(o =>
    {
        o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddFacebook(fb =>
    {
        fb.AppId = Configuration["FacebookAppId"];
        fb.AppSecret = Configuration["FacebookAppSecret"];
        fb.SaveTokens = true;
    });

Tipp

Wenn Sie die Apple-Anmeldung einschließen möchten, können Sie das NuGet-Paket AspNet.Security.OAuth.Apple verwenden. Die vollständige Beispieldatei „Startup.cs“ finden Sie im GitHub-Repository für Essentials.

Hinzufügen eines benutzerdefinierten mobilen Authentifizierungscontrollers

Bei einem mobilen Authentifizierungsflow ist es in der Regel wünschenswert, den Flow direkt für einen vom Benutzer ausgewählten Anbieter zu initiieren (z. B. durch Klicken auf die Schaltfläche „Microsoft“ auf dem Anmeldebildschirm der App). Es ist auch wichtig, dass relevante Informationen über einen bestimmten Rückruf-URI an Ihre App zurückgegeben werden können, um den Authentifizierungsflow zu beenden.

Verwenden Sie dazu einen benutzerdefinierten API-Controller:

[Route("mobileauth")]
[ApiController]
public class AuthController : ControllerBase
{
    const string callbackScheme = "myapp";

    [HttpGet("{scheme}")] // eg: Microsoft, Facebook, Apple, etc
    public async Task Get([FromRoute]string scheme)
    {
        // 1. Initiate authentication flow with the scheme (provider)
        // 2. When the provider calls back to this URL
        //    a. Parse out the result
        //    b. Build the app callback URL
        //    c. Redirect back to the app
    }
}

Der Zweck dieses Controllers besteht darin, das von der App angeforderte Schema (Anbieter) abzuleiten und den Authentifizierungsflow mit dem Anbieter des sozialen Netzwerks zu initiieren. Wenn der Anbieter einen Rückruf an das Web-Back-End durchführt, analysiert der Controller das Ergebnis und nimmt eine Umleitung an den Rückruf-URI der App mit Parametern vor.

Manchmal möchten Sie vielleicht Daten (z. B. access_token des Anbieters) an die App zurückgeben. Dies ist über die Abfrageparameter des Rückruf-URI möglich. Vielleicht möchten Sie auch stattdessen eine eigene Identität auf dem Server erstellen und Ihr eigenes Token an die App zurückgeben. Sie können entscheiden, was und wie Sie es machen.

Sehen Sie sich das vollständige Controller-Beispiel im Essentials-Repository an.

Hinweis

Im obigen Beispiel wird veranschaulicht, wie das Zugriffstoken vom Authentifizierungsdrittanbieter (z. B. OAuth) zurückgegeben wird. Zum Abrufen eines Tokens, mit dem Sie Webanforderungen für das Web-Back-End selbst autorisieren können, sollten Sie ein eigenes Token in Ihrer Web-App erstellen und stattdessen dieses zurückgeben. In der Übersicht über die ASP.NET Core-Authentifizierung finden Sie weitere Informationen zu umfangreicheren Authentifizierungsszenarien in ASP.NET Core.


API