External authentication with Dataverse ServiceClient

by Jul 1, 2024

For a while now we can use the new Dataverse ServiceClient that replaced the old CrmServiceClient. It has three big improvements:

  1. Works for .NET 5.0 and up (.NET Core)
  2. Uses the newer MSAL.NET instead of ADAL.NET (which is out of support) for authentication
  3. Support for async (IOrganizationServiceAsync and IOrganizationServiceAsync2)

Migration is quite easy because the interface of the client is the same.

The default way to create a ServiceClient is by giving it a connection string, like:

ServiceClient serviceClient = 
        new(Configuration.GetConnectionString("myConnection"));

Windows desktop app

But what if you want to use the ServiceClient in a Windows desktop app?

Things become more complicated, because you want to authenticate the user (behalf of flow) and you don’t want to store a connecting string with secrets on the users computer.

ServiceClient can manage access tokens for authenticate internaly, but what if you already managing access tokens in the app and you don’t want ServiceClient do that?

ServiceClient has an option to configure it with redirect authentication to an external function. This function that will be called when the access token is require for interaction with Dataverse.

This function must accept a string (InstanceURI) and return a string (accesstoken), like Func<String,Task<String>>

You can use the specific constructor to do this, but I prefer to use new ConnectionOptions object in this case, like this pseudo code:

static readonly Lazy<IOrganizationService> s_xrmClient = new Lazy<IOrganizationService>(() =>
{
    // Connect using OAuth where access is not managed internally by ServiceClient,
    // but external using an access token provider function
    var connectionOptions = new ConnectionOptions
    {
        AuthenticationType = AuthenticationType.OAuth,
        ServiceUri = new Uri("https://org.crm4.dynamics.com"),
        AccessTokenProviderFunctionAsync = RequestAccessToken
    };

    return new ServiceClient(connectionOptions);

    // Inline method: Retrieve an access token using the registered AccessTokenProvider
    Task<string> RequestAccessToken(string instanceUri)
    {
        var tokenProvider = Host.Services.GetRequiredService<IAccessTokenProvider>();

        return tokenProvider.GetAuthorizationTokenAsync(new Uri(instanceUri));
    }
});

MSAL.NET uses scopes to request access, where the instanceUri will be the scope. Keep in mind that you need to add /.default for the scope to be correct, like:

if (uri != null)
{
    if (!AllowedHostsValidator.IsUrlHostValid(uri))
        return null;

    scopes = new[] { $"{uri.Scheme}://{uri.Host}/.default" };
}

By configuring your ServiceClient like this, you are delegating the authentication to an external caller.

Remy van Duijkeren

Remy van Duijkeren

Power Platform Advisor

Microsoft Power Platform Advisor with over 25 years of experience in IT with a focus on (marketing) automation and integration.

Helping organizations with scaling their business by automating processes on the Power Platform (Dynamics 365).

Expert in Power Platform, Dynamics 365 (Marketing & Sales) and Azure Integration Services. Giving advice and strategy consultancy.

Services:
– Strategy and tactics advise
– Automating and integrating

Subscribe to
The Daily Friction

A daily newsletter on automation and eliminating friction

Related Content

Form Data OnLoad

Form Data OnLoad

You want to call Form OnLoad multiple times? Don't! I was reading about a blogpost to trigger the Form OnLoad multiple times. This should happen after the data was saved and/or refreshed. Why would you want this? Usually, the Form OnLoad contains logic to change the...

read more
Who is the target audience for Power Pages

Who is the target audience for Power Pages

Power Pages is slowly getting better and better product. But then I look at the pricing page: https://powerpages.microsoft.com/en-us/pricing/ Who is the target audience for this product? If you need something 'quick and dirty' it is nice to have a website up and...

read more
Power Pages Secure?

Power Pages Secure?

Power Pages! They tell me it's easy and is very secure, it's built in! I am not fully convinced when I hear this. Why? Simple said: "Easy and Security don't mix". Making something more secure will make it less easy to use. Data separation The thing is, Dataverse is...

read more