05/02/2024
Azure AD-autentificering i din mobilapp: En trinvis guide
I den moderne app-udviklingsverden er sikkerhed altafgørende. Når du bygger mobilapplikationer, der interagerer med cloud-tjenester, er det essentielt at have en robust og sikker autentificeringsmekanisme. Azure Mobile Apps, der er bygget oven på Azure App Services, tilbyder en række muligheder for at håndtere brugerlogin, push-notifikationer og datasynkronisering. Mens Azure-portalen giver mulighed for "serverstyret" autentificering, er "klientstyret" autentificering ofte den foretrukne metode, især for en mere naturlig brugeroplevelse og understøttelse af single sign-on (SSO) og tokenfornyelse.

Denne artikel vil guide dig gennem processen med at implementere klientstyret autentificering ved hjælp af Azure Active Directory (Azure AD) i en Xamarin.Forms mobilapplikation. Vi vil dykke ned i de nødvendige opsætninger i Azure-portalen samt kodningsdetaljerne i din Visual Studio-løsning.
Forståelse af Autentificeringsflows
Før vi går i gang med implementeringen, er det vigtigt at forstå forskellen mellem serverstyret og klientstyret autentificering:
| Funktion | Serverstyret Autentificering | Klientstyret Autentificering |
|---|---|---|
| Initiering | Azure Mobile App Service initierer login-flowet. | Mobilapplikationen initierer login-flowet direkte med identitetsudbyderen (Azure AD). |
| Token Exchange | Azure Mobile App Service håndterer udvekslingen af legitimationsoplysninger med identitetsudbyderen. | Mobilapplikationen indhenter access token fra identitetsudbyderen og sender det direkte til Azure Mobile App Service. |
| Brugeroplevelse | Kan være mindre tilpasselig. | Giver mulighed for en mere naturlig og integreret brugeroplevelse, ofte via SDK'er fra identitetsudbyderen. |
| SSO | Kan være begrænset. | Understøtter typisk single sign-on lettere. |
| Token Fornyelse | Håndteres af tjenesten. | Kan implementeres mere fleksibelt via SDK'er. |
Klientstyret autentificering giver dig mere kontrol og en bedre brugeroplevelse, hvilket gør det til et foretrukket valg for mange udviklere.
Opsætning i Azure-portalen
Før du kan skrive kode, skal du udføre et par kritiske trin i Azure-portalen:
1. Opret og Konfigurer Azure Mobile App
Opret en ny Azure Mobile App Service, hvis du ikke allerede har en. Naviger til din Mobile App-ressource i Azure-portalen.
2. Registrer Webapplikation med Azure AD
Du skal registrere din Azure Mobile App som en webapplikation i din Azure Active Directory. Dette gøres under "App registrations" i Azure AD.
- Gå til din Azure Active Directory.
- Vælg "App registrations" og derefter "New registration".
- Giv applikationen et navn (f.eks. "MyMobileAppBackend").
- Under "Supported account types", vælg den mest passende mulighed for din app.
- Angiv en "Redirect URI". For en webapplikation er dette ofte din Mobile App Service URL efterfulgt af `/.auth/login/done`. Eksempel: `https://your-mobile-app.azurewebsites.net/.auth/login/done`.
- Klik på "Register".
Notér følgende fra din webapplikationsregistrering:
- Application (client) ID: Dette er din client ID for webapplikationen.
- Object ID: Bruges til at oprette issuer URL.
- Directory (tenant) ID: Vigtigt for at definere din tenant.
- Expose an API sektion: Konfigurer en App ID URI her (f.eks. `https://your-tenant.onmicrosoft.com/your-mobile-app-backend`). Dette URI bruges som målgruppe for tokens.
3. Registrer Native Klientapplikation med Azure AD
Du skal også registrere din Xamarin.Forms app som en native klientapplikation i Azure AD. Dette giver din mobilapp tilladelse til at kalde din Azure Mobile App.
- Gå til din Azure Active Directory.
- Vælg "App registrations" og derefter "New registration".
- Giv applikationen et navn (f.eks. "MyMobileAppClient").
- Under "Supported account types", vælg den mest passende mulighed.
- Under "Redirect URI", vælg "Public client/native (mobile & desktop)" og angiv en URI som f.eks. `http://localhost`.
- Klik på "Register".
Notér Application (client) ID for denne native klientapplikation. Dette er den client ID, din mobilapp vil bruge.
4. Konfigurer App Service Authentication
Tilbage i din Azure Mobile App Service skal du konfigurere autentificering:
- Naviger til din Mobile App Service i Azure-portalen.
- Vælg "Authentication" under "Settings".
- Aktiver "App Service authentication".
- Under "Identity provider", vælg "Azure Active Directory".
- Vælg "Advanced" for at konfigurere manuelt.
- Client ID: Indsæt Application (client) ID fra din webapplikationsregistrering (ikke den native klient).
- Issuer URL: Konstruer denne URL ved hjælp af din Directory (tenant) ID: `https://sts.windows.net/{din-directory-id}/`.
- Allowed Token Audiences: Indsæt din App ID URI fra webapplikationsregistreringen.
- Vælg den ønskede "Action to take when request is unauthenticated". "Log in with Azure Active Directory" er typisk det rette valg.
- Gem dine ændringer.
Udvikling i Visual Studio
Nu er vi klar til at implementere autentificeringslogikken i vores Xamarin.Forms-projekt.
Projektstruktur
Din Visual Studio-løsning vil typisk bestå af:
- En ASP.NET Web Application (til din Azure Mobile App backend).
- En Xamarin.Forms projekt (til din cross-platform mobilapp).
Backend Ændringer (ASP.NET Projekt)
For at sikre, at kun autentificerede brugere kan tilgå dine API'er, skal du tilføje `[Authorize]` attributten til dine controllere, der kræver autentificering. Åbn `ValuesController.cs` og tilføj attributten:
[Authorize] public class ValuesController: ApiController { // ... dine metoder ... } Når du har foretaget disse ændringer, skal du publicere din ASP.NET-applikation til den Azure Mobile App Service, du har oprettet.
Frontend Ændringer (Xamarin.Forms Projekt)
1. NuGet Pakker
Åbn NuGet Package Manager for din delte Xamarin.Forms-projekt og sørg for, at alle pakker er opdaterede. Tilføj derefter følgende pakker:
Microsoft.Azure.Mobile.ClientMicrosoft.IdentityModel.Clients.ActiveDirectory
Genopbyg løsningen for at sikre, at alt bygger korrekt.
2. UI Ændringer (MainPage.xaml)
Modificer din `MainPage.xaml` for at inkludere knapper og labels til login og statusvisning:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MobileAppClient" x:Class="MobileAppClient.MainPage"> <StackLayout Orientation="Vertical" Padding="20"> <Button Text="Login med Azure AD" Clicked="OnLoginClicked" /> <Label x:Name="lblHello" Text="" /> <Label x:Name="lblMobileServiceStatus" Text="" /> </StackLayout> </ContentPage> 3. Service Manager Klasse
Opret en `ServiceManager` klasse i din delte projekt. Denne klasse vil håndtere singleton-instansen af `MobileServiceClient`.
using Microsoft.WindowsAzure.MobileServices; using System; namespace MobileAppClient { public class ServiceManager { // TODO: Erstat med din Azure Mobile App URL private readonly string _serviceUrl = @"https://your-mobile-app.azurewebsites.net"; private static ServiceManager _defaultInstance = new ServiceManager(); private MobileServiceClient _client; private ServiceManager() { _client = new MobileServiceClient(_serviceUrl); } public static ServiceManager DefaultManager { get { return _defaultInstance; } private set { _defaultInstance = value; } } public MobileServiceClient CurrentClient { get { return _client; } } } } 4. Implementering af Login Logik (MainPage.xaml.cs)
Åbn `MainPage.xaml.cs` og tilføj følgende kode:
using Microsoft.Identity.Client; using Microsoft.WindowsAzure.MobileServices; using System; using System.Collections.Generic; using System.Threading.Tasks; using Xamarin.Forms; namespace MobileAppClient { public partial class MainPage: ContentPage { // Azure AD Indstillinger - ERSTAT MED DINE VÆRDIER private readonly string _authority = "https://login.microsoftonline.com"; private readonly string _tenant = "your-aad-tenant.onmicrosoft.com"; // Dit Azure AD tenant navn private readonly string _resourceID = "https://your-aad-tenant.onmicrosoft.com/your-mobile-app-backend"; // App ID URI fra backend-registrering private readonly string _clientID = "e1ab7890-1234-4ee0-bc30-5d3bc87c2fd9"; // Client ID fra native klient-registrering private readonly string _redirectUrl = "http://localhost"; // Redirect URI for native klient private ServiceManager _manager = ServiceManager.DefaultManager; public IPlatformParameters PlatformParameters { get; set; } // Bruges til platformspecifikke parametre public MainPage() { InitializeComponent(); } private async void OnLoginClicked(object sender, EventArgs e) { lblHello.Text = "Logger ind..."; lblHello.TextColor = Color.Gray; lblMobileServiceStatus.Text = ""; try { // 1. Indhent Access Token fra Azure AD AuthenticationContext authContext = new AuthenticationContext(string.Format("{0}/{1}", _authority, _tenant)); AuthenticationResult authResult = await authContext.AcquireTokenAsync(_resourceID, _clientID, new Uri(_redirectUrl), PlatformParameters); // Opret payload til login JObject payload = new JObject(); payload["access_token"] = authResult.AccessToken; // Opdater UI med brugerinfo lblHello.Text = string.Format("Velkommen {0}!", authResult.UserInfo.DisplayableId); lblHello.TextColor = Color.Green; // 2. Log ind på Azure Mobile App Service med token MobileServiceUser user = await _manager.CurrentClient.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload); lblMobileServiceStatus.Text = "Succesfuldt forbundet til Azure Mobile App Service"; lblMobileServiceStatus.TextColor = Color.Green; // 3. Kald en beskyttet API (f.eks. ValuesController) try { IEnumerable<string> values = await _manager.CurrentClient.InvokeApiAsync<IEnumerable<string>>("values"); lblMobileServiceStatus.Text += "\nData fra API: " + string.Join(", ", values); } catch (MobileServiceInvalidOperationException apiEx) { lblMobileServiceStatus.Text = string.Format("API Kald Fejlede: {0} {1}", apiEx.Response.StatusCode, apiEx.Response.ReasonPhrase); lblMobileServiceStatus.TextColor = Color.Red; } } catch (Exception ex) { lblHello.Text = "Login Fejlede!"; lblHello.TextColor = Color.Red; lblMobileServiceStatus.Text = $"Fejl: {ex.Message}"; // Log den fulde fejl for debugging System.Diagnostics.Debug.WriteLine(ex.ToString()); } } } } Platformspecifikke Ændringer
For at `IPlatformParameters` kan fungere korrekt, skal du lave små ændringer i dine platformspecifikke projekter. Dette involverer at oprette en `PageRenderer` for `MainPage`.
Android
MainPageRenderer.cs (i `MobileAppClient.Android` projektet):
using Android.App; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using MobileAppClient.Droid; using Microsoft.Identity.Client; [assembly: ExportRenderer(typeof(MainPage), typeof(MainPageRenderer))] namespace MobileAppClient.Droid { public class MainPageRenderer: PageRenderer { private MainPage _page; protected override void OnElementChanged(ElementChangedEventArgs<Page> e) { base.OnElementChanged(e); if (e.NewElement != null) { _page = e.NewElement as MainPage; Activity activity = this.Context as Activity; _page.PlatformParameters = new PlatformParameters(activity); } } } } MainActivity.cs (i `MobileAppClient.Android` projektet):
// ... eksisterende kode ... using Android.Content; using Microsoft.Identity.Client; namespace MobileAppClient.Droid { [Activity(Label = "MobileAppClient", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] public class MainActivity: global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data); } } } iOS
MainPageRenderer.cs (i `MobileAppClient.iOS` projektet):
using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; using MobileAppClient.iOS; using UIKit; using Microsoft.Identity.Client; [assembly: ExportRenderer(typeof(MainPage), typeof(MainPageRenderer))] namespace MobileAppClient.iOS { public class MainPageRenderer: PageRenderer { MainPage _page; public override void ViewDidLoad() { base.ViewDidLoad(); if (Element != null) { _page = Element as MainPage; _page.PlatformParameters = new PlatformParameters(this); } } } } UWP
MainPageRenderer.cs (i `MobileAppClient.UWP` projektet):
using Xamarin.Forms; using Xamarin.Forms.Platform.UWP; using MobileAppClient.UWP; using Windows.Security.Authentication.Web; using Microsoft.Identity.Client; [assembly: ExportRenderer(typeof(MainPage), typeof(MainPageRenderer))] namespace MobileAppClient.UWP { public class MainPageRenderer: PageRenderer { private MobileAppClient.MainPage _page; protected override void OnElementChanged(ElementChangedEventArgs<Page> e) { base.OnElementChanged(e); if (e.NewElement != null) { _page = e.NewElement as MobileAppClient.MainPage; // For UWP, PromptBehavior.Auto er ofte passende _page.PlatformParameters = new PlatformParameters(PromptBehavior.Auto, true); } } } } Afprøvning
Når alle ændringer er implementeret, skal du genopbygge din løsning. Kør applikationen på dine målplatforme (Android-emulator/enhed, iOS-simulator/enhed, UWP-app). Du bør nu kunne klikke på "Login med Azure AD", blive præsenteret for Azure AD's login-side, og efter succesfuld login, se din brugerinformation og resultatet af API-kaldet.
Konklusion
Ved at følge disse trin har du succesfuldt implementeret klientstyret autentificering til din Azure Mobile App ved hjælp af Azure Active Directory med en Xamarin.Forms applikation. Denne metode giver en sikker, fleksibel og brugervenlig løsning til identitetsstyring i dine mobilapps. Husk at tilpasse alle placeholder-værdier (som URL'er, tenant-navne og client IDs) til din specifikke Azure-opsætning.
Denne tilgang kan udvides til at understøtte andre identitetsudbydere, som Azure Mobile App Service understøtter, såsom Google, Facebook, Microsoft Account og Twitter, ved at tilpasse `MobileServiceAuthenticationProvider` og de tilhørende indstillinger.
Ofte Stillede Spørgsmål (FAQ)
Q: Hvad hvis jeg bruger en anden framework end Xamarin.Forms?
A: Principperne for klientstyret autentificering med Azure AD forbliver de samme. Du skal dog tilpasse implementeringen af `IPlatformParameters` og tokenhentningsprocessen til den specifikke platform og framework, du bruger (f.eks. native Android/iOS, React Native, osv.).
Q: Hvorfor fejler mit API-kald med 401 Unauthorized?
A: Dette skyldes oftest, at tokenet ikke er gyldigt, eller at det ikke blev sendt korrekt med anmodningen. Dobbelttjek, at din App ID URI er korrekt konfigureret i både Azure AD-registreringen og i App Service Authentication. Sørg også for, at din Xamarin.Forms-app bruger den korrekte `_resourceID` (App ID URI) til at anmode om tokenet.
Q: Hvordan håndterer jeg token-fornyelse?
A: `Microsoft.IdentityModel.Clients.ActiveDirectory` SDK'et understøtter automatisk token-fornyelse, når du bruger `AcquireTokenAsync`. Hvis du oplever problemer, kan det skyldes, at refresh tokenet er udløbet eller er blevet tilbagekaldt.
Q: Kan jeg bruge Azure AD B2C?
A: Ja, du kan integrere med Azure AD B2C. Processen ligner, men du skal konfigurere din `AuthenticationContext` med B2C-specifikke endpoints og politikker (login, sign-up).
Hvis du vil læse andre artikler, der ligner Azure AD-autentificering i din mobilapp, kan du besøge kategorien Teknologi.
