{"id":890,"date":"2024-11-29T09:50:03","date_gmt":"2024-11-29T08:50:03","guid":{"rendered":"https:\/\/sparrow365.de\/?p=890"},"modified":"2024-12-01T20:18:56","modified_gmt":"2024-12-01T19:18:56","slug":"entra-external-id-to-wordpress-hinzu-fuegen","status":"publish","type":"post","link":"https:\/\/sparrow365.de\/index.php\/2024\/11\/29\/entra-external-id-to-wordpress-hinzu-fuegen\/","title":{"rendered":"Entra External ID to WordPress hinzu f\u00fcgen"},"content":{"rendered":"<p>Nachdem ich <a href=\"https:\/\/sparrow365.de\/index.php\/2024\/10\/28\/windows-365-und-azure-virtual-desktop-conditional-access-deep-dive\/\">in meinem letzten Beitrag<\/a> erkannt hatte, dass ich <strong>unbedingt<\/strong> Kommentare aktivieren sollte, machte ich mich daran, dies auf eine Weise umzusetzen, die meinen pers\u00f6nlichen Anforderungen entspricht. Die naheliegendste L\u00f6sung war dabei von Anfang an, <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/external-id\/external-identities-overview\">Entra External ID<\/a> f\u00fcr Authentifizierung und Benutzerverwaltung hinzuzuf\u00fcgen (<em>wie man es eben so macht<\/em> \ud83d\ude09).<\/p>\n<blockquote>\n<p><em>Entra External ID ist eine Variante von Entra ID (ehemals Azure AD), die f\u00fcr die Verwaltung gro\u00dfer Nutzergruppen gedacht ist, die nicht mit einer Organisation verbunden sind \u2013 typischerweise Kunden. Daher der Branchenbegriff &quot;Customer Identity and Access Management&quot; (CIAM).<\/em><\/p>\n<\/blockquote>\n<p>Nun k\u00f6nnte man denken, dass WordPress, das 40 % des Internets ausmacht, standardm\u00e4\u00dfig \u00fcber ein einfaches und robustes Kommentarsystem verf\u00fcgt. Das trifft auf 99 % der Menschen sicherlich zu. Aber ich bin etwas besonders und habe an mehreren Punkten etwas auszusetzen: <\/p>\n<ol>\n<li><strong>Anonyme Beitr\u00e4ge sind keine Option<\/strong>, da ich mich mit Spam noch weniger auseinandersetzen m\u00f6chte, als ich bereit bin, Benutzerinformationen zu speichern. Nat\u00fcrlich k\u00f6nnte man die Benutzerregistrierung nativ aktivieren und erzwingen, aber:  <\/li>\n<li><strong>Ich mag die WordPress-Anmeldeseite nicht.<\/strong> Besonders, da ich ein gro\u00dfer Fan von Multi-Faktor-Authentifizierung bin und die kostenlosen Optionen oft nicht ideal sind. Ich w\u00fcrde hier viel lieber einen etablierten Identit\u00e4tsanbieter nutzen.  <\/li>\n<li><strong>Die Registrierung erfordert standardm\u00e4\u00dfig immer eine E-Mail-Adresse.<\/strong> Da ich plane, diesen Blog langfristig zu betreiben, w\u00fcrde ich mit der Zeit eine Menge Nutzerinformationen auf meiner Plattform ansammeln. Besonders bei E-Mail-Adressen f\u00fchle ich mich unwohl und w\u00fcrde lieber eine freie Wahl von Benutzernamen erm\u00f6glichen.<\/li>\n<\/ol>\n<p>Abgesehen von den rein praktischen Punkten suchte ich als <strong>Entra ID Admin<\/strong> auch nach einer (semi-)realistischen Gelegenheit, Erfahrungen mit <strong>Entra External ID<\/strong> zu sammeln. Ich habe immer festgestellt, dass <strong>Learning by Doing<\/strong> die effektivste Methode ist.<\/p>\n<hr \/>\n<p><br class=\"\"><\/p>\n<h2>Voraussetzungen<\/h2>\n<p>Ich bin kein Freund davon, in der Produktion zu testen \u2013 auch nicht bei pers\u00f6nlichen Projekten. Daher war der erste Schritt, eine tempor\u00e4re WordPress-Instanz bereitzustellen.<\/p>\n<p>Als Ausgangspunkt habe ich <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/app-service\/quickstart-wordpress\">eine WordPress-Seite auf Azure App Service eingerichtet<\/a>. F\u00fcr meine Zwecke reichte der kostenlose Hosting-Plan vollkommen aus, und die Bereitstellung auf Azure ist schnell und unkompliziert.<\/p>\n<p>Nachdem die Instanz lief, habe ich mein Theme und eine Testseite installiert, um sicherzustellen, dass alles wie auf meiner Produktionsseite funktioniert. Anschlie\u00dfend habe ich die Konfiguration angepasst:<\/p>\n<p><strong>Erster Schritt: WordPress-Kommentare aktivieren und Login-Anforderung einstellen:<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/0_wordpressCommentSettings.png\" alt=\"WordPress-Kommentareinstellungen\" height=\"500\"><\/p>\n<p><strong>So sieht der Kommentarbereich jetzt aus:<\/strong><br \/>\n<img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/1_resultWordpressCommentSettings.png\" alt=\"WordpressCommentResults\" \/><\/p>\n<p>Mit der vorbereiteten WordPress-Seite war es nun an der Zeit, den <strong>Identity Provider (IdP)<\/strong> zu erstellen. Daf\u00fcr habe ich den <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/external-id\/customers\/quickstart-tenant-setup\">Tenant Setup Quickstart<\/a> von Microsoft befolgt.<\/p>\n<blockquote>\n<p><strong>Erinnerung: Dies ist ein neuer, separater Tenant. Erster Schritt: <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/role-based-access-control\/security-emergency-access\">Ein Breakglass-Konto erstellen<\/a>, falls der Zugriff verloren geht.<\/strong><\/p>\n<\/blockquote>\n<p>Jetzt, da beide Teile \u2013 der Service Provider und der Identity Provider \u2013 bereit sind, war es Zeit, die Verbindung herzustellen!<\/p>\n<hr \/>\n<h2>Auswahl eines SSO-Plugins<\/h2>\n<p>WordPress unterst\u00fctzt weder SAML noch OIDC von Haus aus. Das ist verst\u00e4ndlich \u2013 der durchschnittliche Blogger oder Betreiber einer einfachen Webseite hat wohl kaum Bedarf an einer Integration mit Identit\u00e4tsanbietern.<\/p>\n<p>Zum Gl\u00fcck bietet WordPress ein gro\u00dfes \u00d6kosystem von Add-ons und Plugins, die diese L\u00fccke schlie\u00dfen k\u00f6nnen.<\/p>\n<p>Meine Kriterien waren recht einfach:<\/p>\n<ol>\n<li><strong>IdP-Agnostisch<\/strong>: Das Plugin sollte mit jedem Identit\u00e4tsanbieter funktionieren. Tools wie das Auth0 Connector Plugin schieden daher aus.  <\/li>\n<li><strong>Open Source<\/strong>: Ich lege gro\u00dfen Wert darauf, wann immer m\u00f6glich Open-Source-Software zu verwenden.  <\/li>\n<li><strong>OIDC-Protokoll<\/strong>: Ich bevorzuge die Nutzung neuerer Standards, wann immer es m\u00f6glich ist.  <\/li>\n<\/ol>\n<p>Das Plugin, das alle drei Kriterien erf\u00fcllte, war <a href=\"https:\/\/wordpress.org\/plugins\/daggerhart-openid-connect-generic\/&quot;\">Daggerhart OpenID Connect Generic<\/a>.<\/p>\n<p>Nach der Installation dieses Plugins wurde meine WordPress-Testinstanz OIDC-f\u00e4hig. Ab diesem Punkt ging es nur noch um die \u00fcbliche Entra-SSO-Integration.<\/p>\n<hr \/>\n<h2>Konfiguration von SSO in Entra (External) ID<\/h2>\n<p>Zuerst ben\u00f6tigen wir die <strong>Redirect-URI<\/strong> unseres Plugins, um die Konfiguration der Entra Enterprise-App abzuschlie\u00dfen. <em>(In meinem Fall zu finden unter Settings &gt; OpenID Connect Client).<\/em><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/3_RedirectURL.png\" alt=\"WordpressRedirectURL\" \/><\/p>\n<p>Anschlie\u00dfend f\u00fchren wir die erforderlichen Basiseinstellungen auf der Entra-ID-Seite durch.<br \/>\nDas ist meiner Meinung nach der gr\u00f6\u00dfte Vorteil bei der Verwendung von Entra External ID: Wenn man Entra-ID-Admin ist, hat man diese Konfigurationen schon unz\u00e4hlige Male gesehen.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/2_createEnterpriseApp.png\" alt=\"EntraAuthSettings\" \/><\/p>\n<hr \/>\n<p>Nach der Basiskonfiguration sieht die App-Registration so aus:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/4_EntraInitialSettings.png\" alt=\"EntraAuthSettings\" \/><\/p>\n<hr \/>\n<h3>Hinzuf\u00fcgen der Standard-OIDC-Berechtigungen<\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/5_GrantPermissions.png\" alt=\"EntraPermissions\" \/><\/p>\n<blockquote>\n<p>\ud83d\uddb9 <em>Kein Admin-Consent erteilen: Wenn Endbenutzer (z. B. Blogleser) und nicht Ihre Mitarbeiter eingebunden werden, ist es sehr hilfreich, eine explizite Zustimmung zu verlangen. Dies gew\u00e4hrleistet Transparenz und macht die Datenerhebung explizit, was besonders wichtig f\u00fcr die Einhaltung der DSGVO in Europa ist.<\/em><\/p>\n<\/blockquote>\n<hr \/>\n<h2>Konfiguration des OIDC-Plugins<\/h2>\n<p><u>Wichtig! In dem von mir verwendeten Plugin sind die folgenden Felder <strong>verpflichtend<\/strong>. Andernfalls funktioniert der SSO-Button nicht!<\/u><\/p>\n<blockquote>\n<p>Idealerweise sollten die <code>userinfo<\/code>&#8211; und <code>end session<\/code>-URLs dynamisch aus der Konfigurations-URL gelesen werden:<br \/>\n<code>https:\/\/[TenantURL].ciamlogin.com\/[TENANTID]\/v2.0\/.well-known\/openid-configuration<\/code><br \/>\nDoch Entwickler und Standards verstehen sich nicht immer gut. <\/p>\n<\/blockquote>\n<table>\n<thead>\n<tr>\n<th>Einstellung<\/th>\n<th>Wert<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Client ID<\/strong><\/td>\n<td>[Ihre Client-ID]<\/td>\n<\/tr>\n<tr>\n<td><strong>Client Secret Key<\/strong><\/td>\n<td>[Ihr Client-Secret]<\/td>\n<\/tr>\n<tr>\n<td><strong>OpenID Scope<\/strong><\/td>\n<td><code>profile<\/code> <code>openid<\/code> <code>offline_access<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Login Endpoint URL<\/strong><\/td>\n<td><code>https:\/\/[TENANTNAME].ciamlogin.com\/[TENANTID]\/oauth2\/v2.0\/authorize<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Userinfo Endpoint URL<\/strong><\/td>\n<td><code>https:\/\/graph.microsoft.com\/oidc\/userinfo<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Token Validation Endpoint URL<\/strong><\/td>\n<td><code>https:\/\/[TENANTNAME].ciamlogin.com\/[TENANTID]\/oauth2\/v2.0\/token<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>End Session Endpoint URL<\/strong><\/td>\n<td><code>https:\/\/[TENANTNAME].ciamlogin.com\/[TENANTID]\/oauth2\/v2.0\/logout<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Identity Key<\/strong><\/td>\n<td><code>sub<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Nickname Key<\/strong><\/td>\n<td><code>name<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Email Formatting<\/strong><\/td>\n<td>Entfernt, da ich keine E-Mails in meiner Datenbank speichern m\u00f6chte<\/td>\n<\/tr>\n<tr>\n<td><strong>Display Name Formatting<\/strong><\/td>\n<td><code>{name}<\/code>, oder die Claims, aus denen der Anzeigename generiert werden soll<\/td>\n<\/tr>\n<tr>\n<td><strong>State Time Limit<\/strong><\/td>\n<td>360 s (<em>Mit dem Standardwert 180 erhielt ich zu oft &quot;invalid state&quot; \ud83d\ude09<\/em>)<\/td>\n<\/tr>\n<tr>\n<td><strong>Identity with User Name<\/strong><\/td>\n<td>Ja<\/td>\n<\/tr>\n<tr>\n<td><strong>Enable Refresh Token<\/strong><\/td>\n<td>Ja (<em>Daf\u00fcr dient der Scope <code>offline_access<\/code><\/em>)<\/td>\n<\/tr>\n<tr>\n<td><strong>Create user if does not exist<\/strong><\/td>\n<td>Ja<\/td>\n<\/tr>\n<tr>\n<td><strong>Redirect Back to Origin Page<\/strong><\/td>\n<td>Ja<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Ich bevorzuge es immer, <code>userprincipalname<\/code> oder <code>preferred_username<\/code> als Identifikator zu verwenden. Leider nutzt das von mir verwendete Plugin weiterhin den <code>userinfo<\/code>-Endpoint. Das ist ein schlechtes Zeichen f\u00fcr die Integration mit Entra ID, da wir die Informationen vom <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/userinfo#notes-and-caveats-on-the-userinfo-endpoint\">userinfo-Endpoint nicht anpassen k\u00f6nnen<\/a>.<\/p>\n<blockquote>\n<p><em>Falls Ihre L\u00f6sung das Arbeiten mit ID-Tokens erm\u00f6glicht: Ich empfehle diesen <a href=\"https:\/\/martin.rublik.eu\/2024\/10\/15\/testing-claim-rules-with-jwtms.html?utm_source=sparrow365\">Artikel\/Tool zum Testen von Claims<\/a> von Martin Rublik. Auch wenn ich bef\u00fcrchtete, dass mein Plugin den <code>userinfo<\/code>-Endpoint von Anfang an verwendet, habe ich das Tool genutzt, um sicherzustellen, dass das ID-Token korrekt ist, wenn das SSO nicht funktionierte.<\/em><\/p>\n<\/blockquote>\n<p>Mit dieser Konfiguration k\u00f6nnen Nutzer ihre E-Mail angeben, m\u00fcssen es aber nicht \u2013 und wir haben erfolgreich SSO eingerichtet. Schauen wir uns das Ergebnis im Detail an.<\/p>\n<hr \/>\n<h2>Benutzererfahrung<\/h2>\n<p>Wenn wir den Login-Button klicken, der normalerweise zur Standard-WordPress-Anmeldeseite weiterleitet, werden wir jetzt direkt zur Entra External ID-Anmeldeseite weitergeleitet.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/10_pressLoginButton.png\" alt=\"pressLoginButton\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/11_signInDialog.png\" alt=\"loginMas\" \/><\/p>\n<hr \/>\n<p>Nach der Anmeldung mit einem zuvor eingeladenen Benutzer k\u00f6nnen wir uns mit Authenticator MFA anmelden, nachdem wir der Freigabe unserer Informationen zugestimmt haben.<\/p>\n<table>\n<thead>\n<tr>\n<th>1: MFA-Eingabeaufforderung<\/th>\n<th>2: Einverst\u00e4ndniserkl\u00e4rung<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/15_goodOleAuthenticatorMFA.png\" alt=\"mfaPrompt\" \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/6_consentRequest.png\" alt=\"consentRequest\" height=\"500\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<p>Der Benutzer wird erfolgreich angemeldet und k\u00f6nnte eine E-Mail-Adresse angeben, die jedoch standardm\u00e4\u00dfig leer bleibt.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/12_successfullLogin.png\" alt=\"consentPrompt\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/13_emailNotRequired.png\" alt=\"noMailInProfile\" \/><\/p>\n<hr \/>\n<p>Beim Abmelden wird der Microsoft-Kontow\u00e4hler verwendet.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sparrow365.de\/wp-content\/uploads\/2024\/11\/14_logOutDiag.png\" alt=\"logout\" \/><\/p>\n<hr \/>\n<h2>War es den Aufwand wert?<\/h2>\n<p>Wenn Sie jetzt versuchen, auf meinem Blog zu kommentieren, werden Sie eine ganz andere Erfahrung haben. Nach einigen Tests entschied ich mich, ein <a href=\"https:\/\/nextendweb.com\/social-login\/\">Plugin zu verwenden, das sich auf Social Logins spezialisiert<\/a>. Diese L\u00f6sung bietet eine gr\u00f6\u00dfere Auswahl an Social-Login-Anbietern (inklusive dedizierter Login-Buttons) und erm\u00f6glicht es den Nutzern, selbst zu entscheiden, welche Informationen sie teilen.<\/p>\n<p>Ich bin in diesem Blog nicht detailliert auf die Integration mit anderen Identit\u00e4tsanbietern eingegangen, da die Konfiguration und Benutzererfahrung nicht meinen Vorstellungen entsprach. Aber das ist in Ordnung, da Entra External ID f\u00fcr meinen Anwendungsfall nicht vorgesehen ist.<\/p>\n<p>F\u00fcr meinen kleinen Blog w\u00e4re es \u00fcbertrieben, Anmeldeabl\u00e4ufe, Benutzerverwaltungsprozesse oder benutzerdefinierte Seiten zu verwalten. F\u00fcr Entwickler oder Organisationen, die eine robuste Identit\u00e4tsinfrastruktur ben\u00f6tigen, bietet Entra External ID jedoch erhebliche Vorteile, indem es viele Aufgaben abnimmt.<\/p>\n<p>Das gesagt, <strong>hinkt Entra External ID seinem Vorg\u00e4nger <a href=\"https:\/\/learn.microsoft.com\/de-de\/azure\/active-directory-b2c\/overview\">Entra B2C<\/a><\/strong> in einigen Bereichen \u2013 insbesondere bei der Benutzerbereitstellung \u2013 hinterher. Ich kenne aktuelle CIAM-Projekte, bei denen Teams sich nach detailliertem Vergleich aufgrund dieser Einschr\u00e4nkungen f\u00fcr B2C entschieden und auf zuk\u00fcnftige Migrationspfade zu External ID hoffen.<\/p>\n<p>F\u00fcr mich pers\u00f6nlich war das Hauptziel, Erfahrung mit Entra External ID zu sammeln, ein voller Erfolg. Ich habe viel gelernt und wertvolle Praxiserfahrung gesammelt.<\/p>\n<p>Ich bin gespannt, wo sich Entra External ID in den n\u00e4chsten Jahren hinentwickeln wird \u2013 vielleicht werden die L\u00fccken geschlossen, und es wird f\u00fcr eine breitere Palette von Anwendungsf\u00e4llen noch attraktiver. \ud83d\ude0a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nachdem ich in meinem letzten Beitrag erkannt hatte, dass ich unbedingt Kommentare aktivieren sollte, machte ich mich daran, dies auf eine Weise umzusetzen, die meinen pers\u00f6nlichen Anforderungen entspricht. Die naheliegendste L\u00f6sung war dabei von Anfang an, Entra External ID f\u00fcr Authentifizierung und Benutzerverwaltung hinzuzuf\u00fcgen (wie man es eben so macht \ud83d\ude09). Entra External ID ist&#8230; &raquo; <a class=\"read-more-link\" href=\"https:\/\/sparrow365.de\/index.php\/2024\/11\/29\/entra-external-id-to-wordpress-hinzu-fuegen\/\">weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":889,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[72,64,213],"class_list":["post-890","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-me-id","tag-aad","tag-entra","tag-oidc"],"_links":{"self":[{"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/posts\/890","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/comments?post=890"}],"version-history":[{"count":2,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/posts\/890\/revisions"}],"predecessor-version":[{"id":892,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/posts\/890\/revisions\/892"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/media\/889"}],"wp:attachment":[{"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/media?parent=890"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/categories?post=890"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sparrow365.de\/index.php\/wp-json\/wp\/v2\/tags?post=890"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}