After realising that I should really enable comments in my last post, I set out to do so in a way that fits my personal requirements. At the outset, the most obvious solution was adding Entra External ID Authentication and user management (as one does 😉).
Entra External ID is a version of Entra ID (formerly Azure AD) designed for managing large collections of users who aren’t associated with an organization—typically customers. Hence the Industry Term "Customer Identity and Access Management" (CIAM).
Now, one might think that since wordpress makes up 40% of the Internet, it obviously has a simple and robust commenting system by default. Which would be accurate for 99% of people, but I am a special little snowflake, and I take issue with several points:
- Allowing anonymous posting is out of the question, since I want to deal with spam even less than I want to hold user Information. For this you could enable and enforce user registration natively but,
- I don’t like the wordpress login page. Especially since I am a big fan of Multi-Factor Authentication, and the free options are not the nicest. I would much rather have an established identity Provider for this purpose
- Adding to this, the registration flow will always require an email address by default. Since I hope to run this blog for a while, I would slowly accumulate user information on my platform. I feel most uncomfortable with Email Addresses and would prefer free choice of usernames.
Outside of the purely practical points, since I am an Entra ID Admin I was also looking for a (semi) reasonable chance to build up some experience working with Entra External ID. I have always found learning by doing to be the most effective.
Prerequisites
Now, I am no fan of testing in production, even in my personal projects. So the first thing I need is a temporary WordPress instance.
As a starting point, I spun up a WordPress Site on Azure App Service. For my purposes, the free hosting plan more than sufficed, and the Azure deployment is pretty quick and painless.
Once it was up and running, I installed my theme and a test page, just to make sure everything works as it does on my production site. Then the changes from my configuration:
First order of operations: Enable WordPress Comments with Login Requirement:
What the comment section looks like now:
Now with the WordPress page ready, it was time to create the Identity Provider (IdP). For this I followed the Tenant Setup Quickstart provided by Microsoft.
Reminder: This is a separate new tenant. First step: Create a Breakglass account in case you lose access
Now that both individual parts—the service provider and the identity provider—are ready, it’s time to make the connection!
Choosing an SSO Plugin
Out of the box, WordPress doesn’t support SAML or OIDC natively. This makes sense—there’s likely little demand for integration with identity providers among the average bloggers or single-page users.
Thankfully, WordPress has a large ecosystem of add-ons and plugins that can bridge this gap.
My criteria were rather simple:
- IdP Agnostic: The plugin should work with any identity provider, so tools like the Auth0 Connector Plugin were out
- Open Source: I still strongly believe in using Open Source Software whenever possible
- OIDC Protocol: I prefer using newer standards whenever possible
The plugin that met all three criteria was Daggerhart OpenID Connect Generic
After installing this plugin, my WordPress test instance became OIDC-capable. From here on out, it’s just your usual Entra SSO Integration.
Configuring SSO in Entra (External) ID
First, we need the redirect URI of our plugin so we can complete the Entra Enterprise App configuration (In my case in Settings > OpenID Connect Client)
Then, we complete the required base settings on the Entra ID side.
This is in my opinion the main advantage of using Entra External ID, if you are an Entra ID admin you have seen these configurations a million times.
We add our standard OIDC permissions
🖹 Don’t grant admin consent – if you are onboarding end-users (e.g., blog readers) and not your employees it is very helpful to have explicit consent – Explicit user consent ensures transparency and makes data collection explicit, which is especially crucial for GDPR compliance in Europe.
Configuring the OIDC Plugin
Important! In the plugin I am using the following fields are Mandatory! Otherwise the SSO Sign-In button does nothing!
Ideally, the
userinfo
andend session
URLs should be dynamically read from the configuration URL:https://[TenantURL].ciamlogin.com/[TENANTID]/v2.0/.well-known/openid-configuration
but developers don’t always get along with standards.
Setting | Value |
---|---|
Client ID | [Your Client ID] |
Client Secret Key | [Your Client Secret] |
OpenID Scope | profile openid offline_access |
Login Endpoint URL | https://[TENANTNAME].ciamlogin.com/[TENANTID]/oauth2/v2.0/authorize |
Userinfo Endpoint URL | https://graph.microsoft.com/oidc/userinfo |
Token Validation Endpoint URL | https://[TENANTNAME].ciamlogin.com/[TENANTID]/oauth2/v2.0/token |
End Session Endpoint URL | https://[TENANTNAME].ciamlogin.com/[TENANTID]/oauth2/v2.0/logout |
Identity Key | sub |
Nickname Key | name |
Email Formatting | Cleared, since I don’t want emails in my database |
Display Name Formatting | {name} , or the claims from wich to build the Display name |
State Time Limit | 360 s ( With the Default 180 I was getting "invalid state" too often for my taste 😉) |
Identity with User Name | Yes |
Enable Refresh Token | Yes (This is what the scope offline_access is for) |
Create user if does not exist | Yes |
Redirect Back to Origin Page | Yes |
I always prefer using userprincipalname
or preferred_username
as the identifier, sadly the plugin I use still uses the userinfo Endpoint. This is always a bad sign for integration with Entra ID, since we can’t change the Information from the userinfo Endpoint in Entra ID.
If your solution allows working with ID tokens: I recommend this Article / Tool for Claim Testing from Martin Rublik, while I did fear that my plugin used userinfo from the get-go, I used the tool to verify the ID token to be correct when the SSO did not work
With this configuration, users Can provide their email, but don’t have to – and we have successfully achieved SSO. But let’s look at the result in more detail.
User Experience
If we press the login Button that would usually redirect to the default WordPress Login, we are now immediately redirected to the Entra External ID Login experience.
Then we try logging in with a previously invited User, and can sign in with authenticator MFA, after Consenting to sharing of our information.
1: MFA Prompt | 2: Consent Request |
---|---|
The User is logged in successfully, and could provide an Email Address, but it is empty by default.
On Logout, the Microsoft Account Picker is used.
Was it worth it?
If you try commenting on my blog, you’ll now find a very different experience. After testing, I decided to use a plugin which specialises in Social Logins. This solution has a much larger selection of social providers (including dedicated Login buttons) and also allows me to leave it open to the user what information he shares.
I did not go in depth on the integration with other identity providers in this blog, since the configuration and end user experience is really not what I was looking for – but that’s okay, since Entra External ID is not meant for my use case.
For my little blog, managing login flows, user management processes, or building custom pages is overkill. However, for developers or organizations requiring robust identity infrastructure, Entra External ID offers significant benefits by handling much of the heavy lifting.
That said, Entra External ID still lags behind its predecessor, Entra B2C, in several areas—particularly user provisioning. For example, I know of recent CIAM projects where teams, after a detailed comparison, opted for B2C due to these limitations and hope for future migration paths to External ID.
For me personally, the primary goal of gaining experience with Entra External ID was met. I learned a great deal and gained valuable hands-on practice.
I’m excited to see where Entra External ID might be in the next couple of years—perhaps it will close the gaps and become even more compelling for a wider range of use cases. 😊
Comments