Bei der Verwendung von AVACloud werden meistens Serviceaccounts benutzt um auf die API zuzugreifen. Vor Kurzem hatten wir jedoch einen spannenden Fall: Ein Kunde hat ein Excel AddIn für GAEB erstellt, und dabei die AVACloud benutzt. Hierbei sollten individuelle Dangl.Identity Benutzerkonten verwendet werden, anstatt zentral verwalteter OAuth2 Clients. Da die von uns bereitgestellte AvaCloudClientFactory aus unserem Dangl.AVACloud Paket davon ausgeht, dass mit einem Client gearbeitet wird, musst Du den Code etwas anpassen um mit individuellen Benutzeraccounts zu arbeiten. Folge einfach den nächsten Schritten:
Zuerst erstellen wir eine Klasse UserAccountTokenHandler, die das ITokenHandler Interface implementiert. Diese wird versuchen, einen Json Web Token (JWT) direkt über die AVACloud zu erhalten. Dabei werden Benutzername (oder Email) und Passwort eines Benutzeraccounts verwendet, so dass der JWT einen direkten Nutzerkontext enthält. Das ersetzt den OpenID Connect basierten Client Credentials Authentication Flow der standardmäßig im AVACloud Client benutzt wird. Die Implementierung ist recht übersichtlich, der Token wird durch einen einzigen Aufruf über die AVACloud API erzeugt.
Danach kommt die TokenAccessChecker Klasse, die einfach einen Token abruft und prüft, ob der Benutzer tatsächlich Zugriff zur AVACloud hat. Dadurch können wir eine Benachrichtigung im UI der Anwendung zeigen, falls der Benutzer keine Berechtigungen hat. Das spart uns das Ausprobieren und abfangen eines 403 - Forbidden Statuscodes inm eigentlichen Http Call.
UserAccountHttpClientAccessor dient als kleiner Wrapper um einen HttpClient, um einen typisierten HttpClient mit dem HttpClientFactory Pattern bereitzustellen. Wir könnten alternativ auch Named Clients verwenden, aber für die einfachere Verwaltung in Zukunft gehen wir über eine Wrapperklasse.
Nachdem alles erstellt ist, arbeiten wir noch etwas an der Developer Experience. Es gibt immer einiges an Overhead wenn man mit REST APIs arbeiten, wie z.B. Lifetimemanagement von HttpClient Objekten und die Verwaltung von Tokens und deren Zuordnung zu einzelnen HTTP Requests. Da wir immer stark auf Automatisierung und Wiederverwendbarkeit aus sind, nutzen wir häufig Dependency Injection. Hier generieren wir eine Klasse, die intern den ganzen Lebenszyklus unserer API Aufrufe verwaltet. Hier bedeutet das, wir initialisieren eine einzige Singleton Instanz der AvaCloudUserClientFactory und nutzen diese dann, um Clientobjekte über deren internen ServiceProvider zu erstellen.
Zum Schluss haben wir noch einen kleinen Test geschrieben, der den Workflow darstellt. Dabei wird ein Token erzeuigt, dieser validiert, und dann wird eine Excelkonvertierung mit AVACloud durchgeführt: