Lokalen REST-Webservice mit Azure AD absichern

In diesem Artikel möchte ich euch zeigen, wie man einen lokal gehosteten REST-Webservice mit Azure AD absichern kann. In diesem Beispiel zeige ich euch die Authentifizierung mit einem kleinen PowerShell Skript als Client, dass ein Zertifikat dafür verwendet.

Zuerst benötigen wir zwei App-Registrierungen in unserem Azure AD, eine für den REST-Webservice und eine für den Client (in diesem Fall PowerShell Skript).

REST-Webservice mit Azure AD absichern
Neue App-Registrierung hinzufügen

Wir geben der App-Registrierung für unseren REST-Webservice einen entsprechend Namen, ansonsten müssen wir in diesem Schritt keine weiteren Anpassungen durchführen.

App-Registrierung für REST-Webservice erstellen

Nun erstellen wir eine neue App-Rolle, die für die Verwendung unseres Webservices notwendig ist.

Neue App-Rolle anlegen

Der Rolle geben wir einen aussagekräftigen Namen, Wert und Beschreibung. Ebenfalls definieren wir, dass Anwendungen die zulässigen Mitgliedstypen sind.

App-Rolle erstellen

Nun müssen wir noch die Anwendungs-ID-URI erstellen bzw. festlegen.

Anwendungs-ID-URI

Die vorgeschlagene App-ID-URI kann einfach übernommen, diese ist später für den Client relevant.

App-ID-URI festlegen

Nun sind wir mit dieser App-Registrierung fertig und können die App-Registrierung für den Client anlegen.

Neue App-Registrierung für den Client erstellen

Dieser App-Registrierung geben wir ebenfalls einen aussagekräftigen Namen.

App-Registrierung erstellen

Nun fügen wir der App-Registrierung für den Client eine entsprechende API-Berechtigung für unsere App-Registrierung für unseren REST-Webservice hinzu.

API-Berechtigung hinzufügen
API-Berechtigungen anfordern
Berechtigungen auswählen

Danach müssen wir die angeforderten Berechtigungen noch genehmigen.

Zustimmung erteilen
Administratoreneinwilligung bestätigen
API-Berechtigungen vergeben

Nun müssen wir das Zertifikat in der App-Registrierung noch hinterlegen, über das die Authentifizierung erfolgen soll. Wir exportieren also das Zertifikat ohne privaten Schlüssel und laden es in der App-Registrierung hoch.

Zertifikat hochladen

Nach dem erfolgreichen Hochladen erscheint das Zertifikat mit einigen zusätzlichen Informationen in der Übersicht.

REST-Webservice mit Azure AD absichern
Hochgeladene Zertifikate

Nun haben wir alle Vorbereitungen getroffen und können nun den REST-Webservice mit Azure AD absichern.

In diesem Beispiel erstellen wir mit Visual Studio einfach ein neues ASP.NET Core-Web-API Projekt, dieses beinhaltet bereits einen Demo-Webservice, den wir nutzen können.

REST-Webservice mit Azure AD absichern
Neues Projekt in Visual Studio erstellen

Dem Projekt geben wir ebenfalls einen entsprechenden Namen und lassen es uns erstellen.

REST-Webservice mit Azure AD absichern
Neues Projekt konfigurieren

Die weiteren Informationen können wir auf den Standard-Einstellungen belassen.

REST-Webservice mit Azure AD absichern
Weitere Informationen für das Projekt festlegen

Zuerst passen wir die appsettings.json Datei an, um die Konfiguration für unsere App-Registrierung zu hinterlegen. Die Informationen für den hinzuzufügenden AzureAD Block finden wir in der Übersicht der App-Registrierung.

REST-Webservice mit Azure AD absichern
appsettings.json Konfiguration

REST-Webservice mit Azure AD absichern
Übersicht der App-Registrierung

Hier noch einmal die appsettings.json Datei zum kopieren. Die Werte müssen natürlich entsprechend angepasst werden.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "M365x86804735.onmicrosoft.com",
    "TenantId": "b5e0c1a9-ebf0-4c5b-ae70-928f8a0cb5ba",
    "ClientId": "e32f813c-59d8-4d20-848b-8dbe4c0ac73e"
  }
}

Nun müssen wir noch mit NuGet ein notwendiges Package herunterladen. Dabei handelt es sich um das Microsoft.Identity.Web Package.

REST-Webservice mit Azure AD absichern
Microsoft.Identity.Web Package dem Projekt hinzufügen

Nun müssen wir der Program.cs noch die notwendige Authentifizierungsmethode hinzufügen. Das geschieht in der Zeile 9.

REST-Webservice mit Azure AD absichern
Program.cs mit Erweiterung

Hier noch einmal der gesamte Quellcode zum kopieren.

using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Add WebApiAuthentication
builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

// Add Authentication
app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

Nun müssen wir nur noch unserem REST-Webservice das Authorize Tag hinzufügen. Durch die ausgewählte Vorlage wurde uns der WeatherForecastController.cs automatisch erstellt. Dort fügen wir in Zeile 9 das Tag mit der entsprechenden Rolle hinzu. Die Rolle muss natürlich der entsprechen, der wir in der App-Registrierung verwendet haben.

REST-Webservice mit Azure AD absichern
WeatherForecastController.cs mit Authorize Tag

Und auch hier noch einmal der Quellcode zum kopieren.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Data;

namespace MyOwnRestService.Controllers
{
    [ApiController]
    [Route("[controller]")]
    [Authorize(Roles = "OwnRestService.Use")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

Wenn der REST-Webservice nun läuft, können wir uns um den Client kümmern.

Dafür erstellen wir ein kleines PowerShell Skript mit Hilfe des Az-Moduls.

REST-Webservice mit Azure AD absichern
Client als PowerShell-Skript

Die Parameter in den Zeilen 3-6 müssen natürlich angepasst werden. $clientID und $tenantID erhalten wir aus der Übersicht der App-Registrierung für den Client. Die $resourceUrl ist die App-ID-URI. Und $certThumbprint ist der Thumbprint des zu verwendeten Zertifikats.

In Zeile 8 authentifizieren wir uns mit dem Zertifikat und nutzen den zurück gelieferten Token zur Authentifizierung an unserem lokalen REST-Webservice in Zeile 14.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$clientID = "d7604f70-4e30-4e95-8d42-5bf04389ad63"
$tenantID = "b5e0c1a9-ebf0-4c5b-ae70-928f8a0cb5ba"
$resourceUrl = "api://e32f813c-59d8-4d20-848b-8dbe4c0ac73e"
$certThumbprint = "5b0298e49578aae37571fb03dfe1a694abc09c89"

Connect-AzAccount -CertificateThumbprint $certThumbprint -ApplicationId $clientID -Tenant $tenantID

$azAccessToken = Get-AzAccessToken -ResourceUrl $resourceUrl
$accessToken = $azAccessToken.Token
$headers = @{Authorization = "Bearer $accessToken" }
$contentType = 'application/json; charset=utf-8'
Invoke-RestMethod -ContentType $contentType -Uri 'https://localhost:7281/WeatherForecast' -Method Get -Headers $headers -Body $json -UseBasicParsing

Der größte Aufwand ist die Konfiguration der notwendigen App-Registrierungen. Die Anpassungen im Code des Webservices sind sehr einfach und gering, weil die Unterstützung an dieser Stelle sehr gut von Microsoft ist.

Den kompletten Quellcode findet ihr auch in meinem GitHub Repository.

In diesem Sinne, Happy Coding 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert