For those of you who are interested in utilizing the Adoxio Connect Framework for Dynamics 365 in your own projects, be that a console application, Azure Function App, or an ASP.NET web app then this post will help you understand why we built this framework and the settings that it exposes. The goal of the Adoxio Connect Framework is to make it easy to use the new Dynamics 365 Server-to-Server authentication and help build applications based on this authentication schema without having to take on the management overhead of authentication.
When looking at the history of the Dynamics platform and how you built applications for it, you always had to do some sort of impersonation or maintain a service account of some sort. You could utilize a non-interactive user if you wanted to try to avoid taking up a license but this had a number of limitations with it and you actually still needed a user license to initially set it up. With Dynamics 365, Microsoft launched Server-to-Server authentication, or often referred to as S2S auth, that removes the previous need of a user account.
Developers over the last number of years have already been very used to this Server-to-Server type of authentication schema in that it was client credential or certificate based authentication and not user credential based. What that means is you have either a client ID and client secret or use client certificates as your credentials, you don’t need a user license at any step of the process. This is actually the proper way to authenticate an application as a service, like a portal or a scheduled process. Many mistake the Dynamics 365 Server-to-Server authentication as only for use with multi-tenant applications, meaning 1 code base or 1 service that accesses many different tenants, like AppSource applications, when in fact it can be used in multi-tenant as well as single tenant scenarios.
A really good example of a single tenant scenario is a portal or web app, and this is how the Dynamics 365 portal itself (or CRM portal if your still on the initial Microsoft release) does its authentication with the Dynamics instance (they use a slightly different version but the concepts are the same). A portal or web app is an application that runs as a service on a server, the users accessing the application are often not Dynamics users, they are external to the organization and it needs to basically be always on.
At present the Xrm tooling API library with the CrmServerClient does not easily support or provide the easy constructs to create a server-to-server auth based client. This is really due to the Active Directory Authentication Library (ADAL) and how it works in certain versions. As a result you need to do a lot of the figuring out and management of the ADAL yourself and requires you to really understand the concepts at play.
The Adoxio Connect Framework is meant to fill that gap in the Xrm tooling API and make using Server-to-Server authentication super easy, especially in a web app. You don’t have to worry about tokens, how to get them, attach them, etc., you just plug-in some settings and construct the context. The framework is not limited to only a web app, you can easily plug it into console applications, Azure Function Apps or any other .NET based applications. It allows you to construct a S2S auth based context, which we have called CrmContext (yes CRM, it is still CrmServiceClient 🙂 ) with a couple of settings and then you can utilize that context in various ways. CrmContext implements OrganizationWebProxyClient and then uses ADAL to get an Oauth bearer token and will attach it to the web proxy client. It figures out the hard bits for you, all you as a developer need to worry about is then using that context. To help make using it even easier the CrmContext also has an OrganizationServiceContext so that you can start using the Linq provider right away as well.
Part of making that easy is making sure you just have to add a couple of settings to the application. Those use to Adxstudio Portals development will know entering a connection string that consisted of an instance or organization URL, username and password. The Adoxio Connect Framework isn’t much different, it requires a resource (instance URL), client ID, client secret and the Azure AD tenant identifier. All of these can be stored in 2 different ways currently, either as appSettings in an application or web configuration file or as a settings.json. The framework contains a SettingManager to help assist with loading, validating and even saving the settings to they can persist through application restarts if you aren’t using a configuration file. Below is some example settings (they don’t actually work) of how you would put it in a configuration file.
<add key="dyn:SdkClientVersion" value="8.2" />
<add key="dyn:ClientId" value="1d8925fd-8cbe-4f07-a83f-f59f7b111350" />
<add key="dyn:ClientSecret" value="ckrtN4TrckIAF1i5ccEcJw+C4/ESfcyjWGBRBI80a3A=" />
<add key="dyn:Resource" value="https://connectexampleinstance.crm.dynamics.com" />
<add key="dyn:TenantId" value="ae83bd39-7849-4089-3965-1e5749dc4dc2" />
You’ll also notice dyn:SdkClientVersion in that list. This one is optional, if you want to override the version of the SDK being used on the service endpoint and we haven’t updated the library to that version yet you can make that override yourself. If you don’t include the setting it will currently default to 8.2. The setting allows you to change the version in the following service endpoint URI:
At this point you might be asking how do I get a client ID and client secret and where the heck do I get my tenant ID from. This process could be a blog post of its own, which a couple of others have already done, as well as there is MSDN documentation on the process so I am going to refer you to them for the time being (let me know in the comments if you want to see this as a post).
The short is, you need to create an Azure AD application (so you’re going to need to be or need to get your Azure AD admin to assist you), this will giving you a client ID. Once you have an application you can define a client secret for it, and then assign the application permission to the Dynamics Online service. Within Azure AD you can also find your tenant ID. Once you have those you need to then create an Application User in Dynamics and assign it a non-default (not an out of box security role). Don’t copy the System Administrator role, for your sake and everyone’s create a proper security role restricted to the entities the service application actually needs. You will then need to consent or authorize the application. Once you have that process complete, your set, it never has to be done again for that organization instance.
It gets really simple now, you have either your appSettings defined or you have defined your own process to use the Save function in the SettingsManager to write a settings.json. You can now just use the default constructor of CrmContext and it will default to Load function in SettingManager which looks in both locations (appSettings first) and utilizes those in instantiating the OrganizationWebProxyClient in CrmContext.
using (var context = new CrmContext())
var contacts = context.ServiceContext.CreateQuery("contact").Select(a => a.GetAttributeValue<string>("fullname"));
foreach (var contact in contacts)
You’re done, you now have an IOrganizationService (OrganizationWebProxyClient) and an OrganizationServiceContext. You can make requests (Execute, Retrieve, RetrieveMultiple) and the full Linq provider (CreateQuery, UpdateObject, AddObject, etc.) at your disposal. If you want to use Xrm.Tooling, you can as well since CrmServiceClient has a constructor that takes OrganizationWebProxyClient as a parameter.
using (var context = new CrmContext())
using (var serviceClient = new CrmServiceClient(context.WebProxyClient)
// insert CrmServiceClient calls
Let’s talk about licensing for a quick bit here. We have made this open source using GNU LGPLv3. You should go read the details of that license but we have done this with good reason. I got asked this a lot at Extreme, “You guys are giving this away?! With the source code?!”. Yes, we want everyone to be successful with portals, as well as Dynamics and we think this is a little bit of help to kick start everyone with the new authentication schema. You’re free to fork or clone this repo into your own projects but LGPL also means if you enhance or modify this framework you too have to contribute it back and make it open source. You think you want another constructor or make some other addition to the framework? Make a pull request on the GitHub repo, we are all ears. Please contribute and collaborate with us as we want to grow and improve this framework, it’s going to benefit all of us.
How do you get it? The most current and all past versions will always be available on NuGet. You can easily put it in any project just by using the NuGet package manager, just search for Adoxio. Or by running the following from the NuGet Package Manager Console:
The complete source code is published on the Adoxio GitHub if you want a look at the details.
Next post I will specifically discuss utilizing the CrmContext in an ASP.NET web app and you can see how easy it is to make it available everywhere in your web application.
Note: This post also appears on Adoxio Business Solutions Team Blog.