This article describes things I recently learned about how custom clients should authenticate to Dataverse.
I was prompted to write this article when I tried to make sense of authentication options in one of my favourite integration tools, KingswaySoft.
This article intentionally does not provide step by step instructions on how to configure anything. There are loads of blogs and articles that describe how to set things up; there is no point in me repeating them here. Instead, this article is intended as a high-level overview so that you are better placed to understand those articles.
I have included links to resources that provide more detail and those that helped me learn about this topic.
Note: this article is not relevant for Dynamics 365 On-Premises systems.
I am grateful to Joe Griffin who reviewed my article.
Although I have taken care to ensure what I describe in this article is accurate, I am not an expert in identity management, my experience is with Dynamics 365 and the Power Platform.
If you do spot any errors, please let me know so that I can correct the article.
A few definitions
Authentication - confirming the identify of a user or process that is connecting to Dataverse.
Authorization - determining the rights and privileges that a user has. In Dataverse, this is managed using security roles. This article is not concerned with authorization.
Custom Client – a custom application that connects to Dataverse, such as a C# program, integration service, app that is installed on a device or code on a web site.
Microsoft Dataverse – the underlying data platform for Dynamics 365 and Power Platform apps.
Deprecated – intention to remove a feature at some time in the future, but the feature still works until removal.
OAuth – The OAuth 2.0 Authorization Framework (and not the OAuth 1.0 protocol).
Authenticating to Dataverse
For many years custom clients authenticated to Dataverse using the WS-Trust authentication type (also referred to as Office 365). This authentication type was deprecated in February 2020 but at the time of writing (July 2021) still works for some environments.
This Microsoft article, Deprecation of Office 365 authentication type describes the time line for when WS-Trust will be removed.
Two key dates from that article, are:
- April 2021 - WS-Trust not available for any new environments
- April 2022 - WS-Trust removed for all environments
If you have custom apps using WS-Trust, review and update them now before it is too late!
Microsoft has provided details on reviewing your code.
The replacement for WS-Trust is OAuth 2.0 authentication. OAuth 2.0 is an authorization framework defined in the Internet standard, RFC 6749.
OAuth roles and protocol flow
OAuth defines four roles:
- resource owner – an entity capable of granting access to a protected resource; often a person
- resource server – a server hosting protected resources such as Dataverse
- client – an application (custom client) making requests to access protected resources at a resource server
- authorization server – the server that issues access token to the client, for Dataverse this is Azure Active Directory
Simplified protocol flow
- The client contacts the authorization server with an authorization grant requesting an access token
- The authorization server issues an access token
- The client uses the access token to access protected resources
A key feature of OAuth is that an end-user’s credentials are never sent to a resource server. The authorization server acts as an intermediary.
Authenticate to Dataverse with OAuth
For a custom client to authenticate to Dataverse using OAuth0 the process described in the simplified protocol flow above requires an Azure App Registration (which represents the custom client) to be configured.
The app registration process creates a client id (also called an application id).
To “prove” its identity and obtain a token, the custom client must provide its client id and a client secret which can be a text string or a certificate. Nearly all the articles I have seen use a text string for the client secret.
The app registration must be configured with the Dynamics CRM user_impersonation delegated permission for both the impersonation and server to server scenarios described below.
If the custom client connects to Dataverse on behalf of an end-user, then as far as Dataverse is concerned, any actions are performed by the end-user and not the custom client itself.
This means that the custom client must use the end-user’s username and password as well as the client id and client secret to authenticate to Azure Active Directory when requesting an access token.
This screenshot shows how to configure the CDS connection manager in KingswaySoft to use an app registration with impersonation.
An application user is not required in Dataverse.
All operations against the Dataverse environment will be in the name of the user entered in User Name.
In Client App Id and Client Secret type the app registration application id and the secret configured for the app registration.
OAuth0 calls this the Resource Owner Password Credentials Grant.
The OAuth 2.0 Security Best Current Practice states that this grant type must not be used.
Whether this is a good or bad idea is beyond the scope of this article. There are many articles on this topic, one I like is the discussion at auth0. A significant objections is that user credentials are provided to the client which seems to defeat the point of OAuth.
Server to Server authentication
If the custom client does not connect to Dataverse on behalf of end-users (such as in integration scenarios) then you should use Server to Server authentication (S2S).
This means that the custom client authenticates as itself. OAuth calls this the Client Credential Grant.
An Azure app registration is still required. You must also create an Application User in Dataverse and assign appropriate security role(s) to the application user to control what the client application is allowed to do.
A paid license is not required for an application user account used with S2S authentication.
This screenshot shows how to configure the CDS connection manager in KingswaySoft to use an app registration with S2S.
This configuration also requires an app registration and an application user in Dataverse for the application id of the app registration. You must assign the appropriate security roles to the application user.
All operations against the Dataverse environment will be in the name of the application user.
As well as application users there are other types of non-licensed users in Dataverse.
Non-interactive users have been available for some time. They can be used by custom clients to access Dataverse.
Non-interactive users do not require a license, but a license is temporarily needed to create a non-interactive user. In summary, the process is:
- Create user as normal in Microsoft 365
- Assign a license
- After the user appears in D365, change the access mode to non-interactive
- Then in Microsoft 365 admin center, remove the license
You can create up to seven non-interactive users in an environment.
I have already described the use of application users for OAuth authentication.
Application users are created as non-interactive users, but they do not count towards the limit of seven non-interactive user accounts.
Unlike, non-interactive users described earlier, you do not create the user in Microsoft 365, and you do not need to mess around with assigning and then removing a license.
Administrative users are for those that manage an environment and not need functionality. An administrative user has access to environment settings and administration only.
An administrative user does not require a license and the process to create an administrative user is the as for creating a non-interactive user except in the change access mode step, set the access mode to Administrative.
Setting the Access Mode
The Access Mode setting is on the Administration tab of the user form.
Request Limits for Non-Licensed Users
The Power Platform implements rate limits for requests. This is described at Request limits and allocations.
You should review the section on Request limits not based on licensed users or flows for non-licensed users.
At the time of writing the limit depends on the type of purchased subscriptions in the tenant. The most generous limit is 100,000 requests (shared between all non-licensed users) per 24 hours for tenants with at least one Dynamics 365 enterprise subscription.
Application User or Non-Interactive User?
You might be asking should I use an application User or a non-interactive user? I certainly did and have concluded that I should now only use application users.
Here is my thinking:
- Non-interactive users are messier to set up
- Only seven non-interactive users can be created
- OAuth authentication will be required for your environment (if not already), so an Azure app registration is required anyway
If you have any thoughts on this, I would love to hear them.
Consent is another aspect of app registrations that you need to manage. Consent means agreeing for an application to try to use specific permissions.
If you see an error message like the screenshot below, then a consent is missing for a permission.
It is possible to configure a custom client to ask for the necessary consents or for an administrator to provide the consent on behalf of an organization.
Another reason to start using application users is the removal of the regional discovery services.
The discovery service APIs are used to discover Dataverse environments.
The regional discovery services were deprecated in March 2020 and final removed in June 2021. The global discovery service must be used to discover organizational instances.
The global discovery service is only available when using the RESTful API and this in turn requires an OAuth access token which in turn means that you will need to configure an Azure app registration.
In summary, I have described the need to use app registrations and OAuth for custom clients connecting to Dataverse.
The one thing I urge you to do is to review any in-house custom applications to see if they use WS-Trust and if you start planning the change to OAuth.