Das Pattern "Backend for Frontend" (BFF) ist 2015 aufgekommen, um den Bedürfnissen verschiedener Clients gerecht zu werden und einem General Purpose Backend entgegen zu wirken. Denn Erfahrungen zeigten, dass verschiedene Clients verschiedene Anforderungen erfüllen müssen und es dafür Backend-Services braucht. Es soll damit eine Aufteilung der Verantwortlichkeiten erreicht werden, um die Back-Ends in ihrem Umfang kleiner und damit wartungsfreundlicher zu gestalten.
Nun ist im Kontext von Digital Consulting die Unterstützung von verschiedenen Clients eher selten. Im Enterprise-Umfeld der USU sind es eher Anwendungen, welche auf einen Client beschränkt sind. In der Regel sind es Web-Front-Ends, welche erstellt werden.
In der letzten Zeit hat sich die Auslegung dieses BFF- Begriffes jedoch ein wenig entwickelt. Es ist die Rede davon, dass querschnittliche Aufgaben ebenfalls gut in einem solchen BFF untergebracht sind, zum Beispiel aus der Perspektive der Sicherheit.
Ich habe das Pattern eher domain-orientiert also fachlich interpretiert. Bei Querschnittlichen Aspekten wäre mir der Begriff Proxy oder Gateway intuitiver. Vielleicht hilft es dem einen oder anderen, zunächst mit diesen Begriffen zu arbeiten.
Web-Front-Ends haben sich in den letzten Jahren stetig weiterentwickelt und haben sich von der originären Ausprägung, dass eine Site durch eine Domain bereitgestellt wird, entfernt. Die Buzz-Words der Branche heißen Micro-Services und Micro-Frontends, welche sich aus dem Kerngedanken entwickelt haben, Systeme wieder mehr aufzuteilen, am besten fachlich, nach Domain Driven Design.
Verteilte Systeme sind keine neue Erfindung. Nur waren Sie in dem Web-Umfeld nicht der Standard. Der Fortschritt hat dabei bemerkenswerte Möglichkeiten geschaffen.
Als Meilenstein sei das Thema Module Federation von WebPack genannt. Es erlaubt eine dynamische Komposition von Anwendungsteilen zur Laufzeit in einer Single-Page-Applikation. Dies ermöglicht neue Interaktionsoptionen zwischen Anwendungsteilen, da Sie nun zur Laufzeit in einem Window-Object im Browser operieren (im Unterschied zu IFrame Lösungen). Die Kern-Idee von Micro-Services im Frontend wird somit Realität.
Die SPAs/Front-Ends müssen Cross-Site Kommunikation erlauben. Auch im querschnittlichen Bereich ist Cross-Site Kommunikation gefordert. Kunden wollen SSO, SLO (Single Sign On & Single Logout) und User Federation. Alles soll so verzahnt sein und trotzdem eine gute User Experience bieten. Dadurch sind IAM-Systeme entstanden und haben OAuth, OIDC und SAML mitgebracht.
Der Token-basierte Ansatz ist momentan der Standard. Der Weg hierhin ergibt sich daraus, dass der Sessions-basierte Ansatz mit Cookies zu CSRF-Problemen (Cross-Site Request Forgery) geführt hat. Der Browser sendet die Cookies immer mit, ohne dass etwas getan werden muss.
Die Token-Mechanismen umgehen diese Thematik zwar, weil die Anwendung das Handling der Access-Token steuert. Jedoch hat dies ebenfalls ein neues Problem geschaffen (Cross Site Scripting). SPAs sind öffentliche Clients, und die Inhalte im Browser sind grundsätzlich nicht immer sicher.
Jetzt gibt es natürlich auch Ansätze, um in diesem Fall etwas gegenzusteuern (Closures oder Service Workers). Service Workers, ursprünglich aus dem Ansatz einer PWA und damit einhergehenden Offlinefähigkeit entstanden, arbeiten nach einem Same-Origin Ansatz und können somit in einem getrennten Thread mit separaten Speicherbereich HTTP-Aufrufe intercepten und mit Autorisierung und Authentifizierung Informationen anreichern. Jedoch gibt es auch hier Konstellationen, wo Spectre Attacken auf den Speicherbereich mittels JavaScript möglich sind.
Eine Schlussfolgerung kann somit sein, das Token-Management vom Client in einen Server zu verlagern. Denn Daten, die nicht auf einem System liegen, können nicht abgegriffen werden. Dann bleibt die Frage: Wie ist denn jetzt die Autorisierung und Authentifizierung auf dem Client?
Nun wurden Sessions-Cookie gemieden wegen Cross Site Kommunikation. Entwicklungen im Browser haben nun Same-Site, Secure und HTTPOnly Cookies hervorgebracht. Wenn also die Cross-Site/Cross-Domain unterbunden werden kann, könnte man dies nutzen. Deswegen enthält das BFF Pattern (in diesem speziellen Fall auch Full-BFF genannt) einen Proxy zu den benötigten Services.
Ein Full-BFF kann somit eine Option sein, sich dem Problem Cross-Site-Scripting über den Security by Design-Ansatz zu widmen und sollte bei zukünftigen Projekten in Betracht gezogen werden. Ein weiteres Argument dafür sind die Bestrebungen der Browser-Hersteller, Third-Party Cookies einzuschränken bzw. zu verbieten.
Leider sind die Implementierungen mit OAuth im Kontext von Session-Notification und Silent Renew oft mit Hidden IFrames umgesetzt. Damit sind es automatisch Third-Party-Cookies.
Natürlich können SLO Anteile auch mit Backchannel-orientierten Implementierungen gelöst sein. Das ist aber nicht immer bei allen IAM Produkten der Fall.
Nun hat das Ganze natürlich auch einen Haken. Die Same-Site Cookies haben im Default ein Sandboxing auf die Site und nicht auf die Origin (wie etwa der Service-Worker).
Sub Domain Attacks sind somit ein Einfallstor. Um aber nun dem Einhalt zu gebieten, gilt es, die Option CORS zu verwenden. Um das zu erreichen, werden Requests mit einem Custom Header angereichert. Dies wiederum zwingt den Browser zu einem Preflight CORS Request. Das erlaubt es, auf dem Server nur Requests von einer vertrauenswürdigen Subdomain an zu nehmen.
Wann sollte man sich mit dem Thema BFF befassen? In allen Fällen von Cross Site Kommunikation. Natürlich hat es auch Nachteile. Denn die zentrale Komponente für den Client muss z.B. ggfs. im Bereich der Skalierung individuell behandelt werden. Es ist somit kein Silver-Bullet. Und der Einsatz ist bestimmt auch in das Verhältnis zu setzen zu Schutzbedarfen der Daten in der Anwendung, Aufwand der Entwicklung, Aufwand im Betrieb usw. Aber es ist ein Werkzeug, welches im Jahre 2023 bekannt sein sollte. Zumal es die IETF dieses Jahr als Recommendation herausgegeben hat.
Quellen:
TokenManagement in SPAs:
https://elie29.medium.com/frontend-jwt-token-storage-77cbe6dc680b
https://curity.io/resources/learn/spa-best-practices/
https://about.grabyo.com/service-workers-jwt-tokens/
Service Worker:
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
PWA
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps
https://web.dev/progressive-web-apps/
SameSite Cookie
https://caniuse.com/same-site-cookie-attribute
"Cookie Apocolypse" Third Party Cookies in Browser
https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/
https://www.theverge.com/2021/6/24/22547339/google-chrome-cookiepocalypse-delayed-2023
Module Federation:
https://webpack.js.org/concepts/module-federation/
https://www.heise.de/hintergrund/Die-Micro-Frontend-Revolution-Webpack-5-Module-Federation-4930583.html
CORS Preflight:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests#
https://livebook.manning.com/book/cors-in-action/chapter-4/
Spectre in Service Workers:
https://security.stackexchange.com/questions/255886/does-enabling-sharedarraybuffers-via-service-worker-headerscreate-spectre-vulne
Security BFF:
https://blog.jetbrains.com/dotnet/2022/05/12/securing-spas-and-blazor-applications-using-the-bff-pattern-recording/
BFF in der ursprünglichen Bedeutung:
https://learn.microsoft.com/de-de/azure/architecture/patterns/backends-for-frontends
hier der originale Autor des Patterns: https://samnewman.io/patterns/architectural/bff/
IETF Recommendation:
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps
TMI-BFF (reduzierte Variante) ist zurück zu führen auf folgende Quelle:
https://datatracker.ietf.org/doc/draft-bertocci-oauth2-tmi-bff/
Vergesst folgende Empfehlung nicht: Authorization Code Flow mit PKCE: https://wso2.com/blogs/thesource/securing-spas-best-practices/
Mögliche Umsetzung:
https://github.com/DuendeSoftware/BFF
Apache Based:
https://hanszandbelt.wordpress.com/2017/02/24/openid-connect-for-single-page-applications/
https://github.com/OpenIDC/mod_auth_openidc/wiki/Single-Page-Applications