Jak uzyskać dostęp za pomocą użytkownika do aplikacji zabezpieczonej Service Principalem w Azure?
Scenariusz zakłada posiadanie dwóch aplikacji. Jedna z nich wystawia API dla drugiej MVC. Dalej we wpisie aplikację wystawiającą API będę nazywał po prostu API, natomiast strzelającą do niej nbazwę MVC. Aplikacje są spięte ze sobą za pomocą AAD (Azure Active Directory). Aplikacja, która strzela do API włączone ma Managed Identity. Aplikacja z API włączoną ma Autoryzację po stronie Azure za pomocą AAD.
Zanim zaczniemy – Włączanie autoryzacji
Po pierwsze nalezy włączyć autoryzację i uwierzytelnianie w WebApp w Azure. Można to zrobić w portalu zgodnie z poradnikiem: https://docs.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad
Lub za pomocą skryptu:
Dodawanie roli
Następnie należy do nowo utworzonej aplikacji AAD dodać rolę, w której przypięty będzie użytkownik. Można to zrbić na dwa sposoby:
- Edytując Manifest: Azure Active Directory → App registrations → {nazwa aplikacji} → Manifest
- Używając poniższego skryptu:
Dodawanie użytkownika
W celu przypisania użytkownika do naszej aplikacji w roli nalezy przejść na portal.azure.com i wykonać kolejno kroki:
- Przechodzimy do:
Azure Active Directory → Enterprise Applications → {nazwa aplikacji} → Users and Groups
; - Klikamy na przycisk: [+ Add user] na górze listy;
- Klikamy na zakładkę users and groups;
- Wybieramy użytkownika/-ów którego chcemy przypiąć;
- Jeśli mamy zdefiniowaną więcej niż jedną rolę, wybieramy te, w których chcemy przypiąć użytkownika.
Konfiguracja w kodzie
Przykładowy serwis, wysyłający zapytania z aplikacji MVC do API zabezpieczonego aplikacją AAD możesz zobaczyć w moim projekcie AadAccess na GitHubie. Pobieranie tokenu do tegfo zapytania realizowane jeswt w klasie ManagedIdentityRequestToken.cs:
namespace AadAccess.MVC.Services
{
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Services.AppAuthentication;
public class ManagedIdentityRequestToken
{
public async Task<string> GetToken(string appId)
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
return await azureServiceTokenProvider.GetAccessTokenAsync(appId);
}
}
}
Żeby uzysakć taki token musimy mieć ApplicationId (AppId) aplikacji AAD. W przykładowym serwisie, do którego link jewst wyżej, wartość ta jest pobierana z App Settings. Lecz skąd wziąć to id? Przechodzimy w portalu do: Azure Active Directory → Enterprise Applications → {nazwa aplikacji}
. Application Id znajduje się na górze w sekcji properties:
Wykonanie zapytania
Żeby móc się zautoryzować jako użytkownik musimy zalogować się za pomocą komendy az login (wchodzącej w skład narzędzia Azure CLI).
W momencie wykonywania zapytania HTTP z localhosta z aplikacji nazwanej MVC naszym oczom ukaże się błąd: AADSTS65001: The user or administrator has not consented to use the application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' named 'Microsoft Azure CLI'.
.
Jak go rozwiązać? W portalu Azure przechdzimy do: Azure Active Directory → App registrations → {nazwa aplikacji} → Expose an API
. Należy upewnić się, że dodany jest scope user_impersonation:
Aby dodać aplikację Azure CLI nalezy, wejść w opcję: Add a client application
. W polu Client Id podajemy id: 04b07795-8ddb-461a-bbee-02f9e1bf7b46
, oraz zaznaczamy scope z user_impersonation
na końcu URLa. Wpisane id to id aplikacji Azure CLI, za pomocą której logowaliśmy się na początku tego akapitu. Po dodaniu należy odczekać około 5-10 minut na propagację przypięcia.
Po wykonaniu zapytania http, tym razem uzyskujemy dostęp do aplikacji.
Podsumowanie
W tym wpisie pokazałem jak autoryzować się w Web/Function App na Azure zabezpieczonych aplikacją AAD. W tym celu spieliśmy użytkownika z aplikacją w odpowiedniej roli. Pokazałem, też jak wygląda kod w C# obsługujący uzyskiwanie tokenu autoryzującego zapytanie http. Na koniec dodaliśmy Application Id Azure CLI do naszej aplikacji stojącej „na straży” API. Zostało to wyklonane w celu autoryzacji użytkownika z środowiska localhost do używania aplikacji na Azure.