Azure AD based protection for the WordPress REST API
Introduction
Use this guide if you want to protect your WordPress REST API endpoints with oauth access tokens for delegated access generated by Azure Active Directory (also referred to as Azure AD, AAD). If you enable WPO365's Azure AD based endpoint protection for the WordPress REST API then applications requesting data from any of the protected endpoints will either receive a 401 (unauthorized) or 403 (forbidden) error, unless they present a valid oauth access token that:
- Has been signed by Azure AD.
- Was created for the right Audience (identified by the Azure AD Application ID URI).
- And was created for the custom scope used to further restrict access to the API's data and functionality.
If a valid oauth access token has been provided, then the plugin will try and impersonate the user that sent the request, if that user can be found in WordPress.
Please note The WPO365 plugin tries to find a user by its Azure AD Object ID, the WordPress username (if it's the same as the Azure AD username) or the WordPress email address. All of these user attributes (and many more) can be easily synchronized using - for example - the WPO365 | SYNC bundle.
Protecting your WordPress REST API with oauth access tokens from Azure AD only makes sense if the application that is requesting data from any of the protected endpoints is able to request oauth access tokens from Azure AD. One example of such an application is a native mobile application. To be able to request access tokens, a mobile application must first authenticate a user with Azure AD. Upon successful authentication it will receive an authorization code. Only then can the mobile application go ahead and use that authorization code and exchange it for an access token (and a refresh token to request more tokens over time) for the given audience and scope.
Please note Authentication with Microsoft for native mobile clients and single page applications is not a feature of the WPO365 | LOGIN plugin. Instead developers of these applications have a wide choice of available libraries which they can choose to implement.
From the previous note it follows that Azure AD based protection for the WordPress REST API and guidance provided in this article is especially interesting for developers of JavaScript based single page applications and / or developers of native mobile apps.
This article aims to explain the following steps needed to update the configuration of your WordPress website's App registration in Azure AD to be able to configure the Azure AD based protection for your WordPress REST API:
- Create a globally unique identifier called Application ID URI for the App registration that represents your WordPress website in Azure AD as a user (principal).
- Expose a (WordPress default / custom REST) API by defining a scope.
- Authorize applications to use the exposed API without the need for an (Azure AD global) administrator to consent.
Before you start
- You are a Global Administrator for your company’s Microsoft Office 365 tenant / Azure AD directory (or have at least the ability to edit the Azure Active Directory App registration that was created previously when the single sign-on capability was configured).
- You are an Administrator for your WordPress website.
- You have installed one of the following extensions / bundles:
Create an Azure AD App registration and expose an API
For this article we will assume that you have already registered an application in Azure AD to enable Microsoft based single sign-on (see https://docs.wpo365.com/article/154-aad-single-sign-for-wordpress-using-auth-code-flow for details and steps to accomplish this task). We will also assume that you will use this App registration for your mobile app or single-page application. This can be easily achieved by adding the corresponding platform on the App registration's Authentication page and defining a redirect URI.
- Navigate to Azure Portal Azure Active Directory App registrations and find the app that you registered to enable Microsoft bases single sign-on for your WordPress website.
- Continue to the App registration's Expose an API page.
- Find the Application ID URI input field at the top of the page and click the Set button. To ensure that the Application ID URI is globally unique you can use one of the custom domains that have registered with Azure AD and the App registration's own application client ID. As a prefix you should use api://. In the example of WPO365 we used our domain name (= wpo365.com) and the application's client ID (= c255309b-ca80-43fa-a7cd-1f43cfc98492) and thus the Application ID URI becomes api://wpo365.com/c255309b-ca80-43fa-a7cd-1f43cfc98492.
- Now scroll down to Scopes defined by this API and click + Add a scope.
- Fill out the form, for example with the following values.
- Scope name access_as_user
- Who can consent? Admins only
- Admin consent display name Apps can access the user’s profile.
- Admin consent description Apps can call the app’s web APIs as the current user.
- User consent display name Apps can access your profile and make requests on your behalf.
- User consent description Apps can call this app’s APIs with the same rights as you have.
- State Enabled
- Click Add scope to save and enable the new scope. This will create a new scope that is then referred to as api://wpo365.com/c255309b-ca80-43fa-a7cd-1f43cfc98492/access_as_user. Note the similarity to standard Microsoft scopes e.g. https://graph.microsoft.com/User.Read.
- Now scroll down to Authorized client applications and add the App registration's own application client ID to the list.
Please note Adding the App registration's own application client ID as an authorized application is essential if this App registration is also used by the mobile app or single page application to authentication users with Microsoft. In that case those apps and application will use that same App registration to request access tokens - for example - to access data and logic provided by APIs that are protected by Azure AD. So those apps and applications will request access tokens from the same App registration that is also exposing the WordPress REST API as an API of its own. This is not always true, of course. However, this is true for the example configuration in this article. Adding the App registration's own application client ID also allows the WPO365 | LOGIN plugin to request an access token for our WordPress REST API when it runs the plugin's self-test.
Enable Azure AD based WordPress REST API endpoint protection
Complete the following steps to enable Azure AD based endpoint protection for your WordPress REST API with the WPO365 plugin.
- Open a new browser tab (leave the tab with your App registration open so you can easily copy some of the values) and go to WP Admin > WPO365 > Integration.
- Scroll down to Azure AD based protection for the WordPress REST API.
- Click to Enable cookie based WordPress REST API protection.
- Select the App registration's Application client ID that you want re-configured in the previous step and that now exposes the WordPress REST API.
- Copy and paste the Application ID URI that you defined in the previous step.
- Protect an endpoint by entering the following details:
- The endpoint's path e.g. /wp-json/wp/v2/users/me. If you enter an incomplete path e.g. /wp-json/wp/v2 then be aware that all requests to endpoints starting with /wp-json/wp/v2 will be subject to the protection defined by this configuration
- The HTTP methods for which the protection should be activated as a comma separated string e.g. post or get, post.
- The custom scope that is required to access this endpoint. This scope must be one of the custom scopes that you defined in the previous step. In our example that would be api://wpo365.com/c255309b-ca80-43fa-a7cd-1f43cfc98492/access_as_user.
- If you want to Block all other WordPress REST endpoints you can check the corresponding option.
- Click Save configuration.
Important
If you selected the Intranet Authentication scenario (on the plugin's Single Sign-on configuration page) then the plugin will - by default - block access to all your WordPress REST API endpoints. To work-around this, you must add the path of endpoints that you want to protect to the list of Pages freed from authentication (also on the plugin's Single Sign-on configuration page). Also refer to the online documentation for the Authentication scenario documentation.
Access a protected endpoint
Once the configuration of the registered application in Azure AD has been updated and the endpoint protection has been in enabled using the WPO365 configuration pages, you can now try for your self. Requests that try to access data or functionality using a protected endpoint will need to present a valid Azure AD access token. They must therefore provide an Authorization header with the access token as bearer (shown below is screenshot of such a header produced using the Fiddler tool).
Troubleshooting
Test your configuration
To test your configuration go to WP Admin > WPO365 > Plugin self-test and click to start the self-test. Please note that the self-test is only working correctly if you also configured Microsoft based single sign-on for your website.
Authorization header not found
Some Apache servers and PHP modules such as mod_security may block / remove incoming Authorization headers. If you configured Azure AD based protection for WordPress API endpoints and the plugin cannot find the Authorization header it will generate an error which is visible when you navigate to WP Admin > WPO365.