Hi,
I was hearing some requirement to connect to CRM Webapi from a console application. but never got a chance to really check. However, here are the steps that has to be foollwed and the code.
To connect CRM Web Api there are two steps.
1) Register the Application with the Azure Subscription
2) Build the Console Application to connect to CRM Web Api by using Client ID and Authority URL.
Just one thing to remember is the below process works if both CRM and Azure are under same tenant. If they are different tenant, we have to follow different process. Will try to write it next time.
Register the Application
1) Login to https://portal.azure.com and navigate to Azure Active Directory and click on New Application Registration button.
2) Enter the Name (whatever you wish). You can use any name which should be unique in the App Registrations.
3) Selecte Application Type as Native as we are not building any WebApplicaton/Web Api.
4) Next is Redirect URL. This is something, AD will redirect once the Authentication is done. You can put anything in the following format as we are calling this from Console Application.
XXXXXXX://XXXXXX
Note this URL as we need this in the Console Application
5) Click on the Create button to Register the App. Once the App is registred, you will get the Application ID.
6) Go to the settings of the app -> Required Permissions -> Add -> Select an API -> Dynamics CRM Online -> Select
7) And in the same place, click on Select Permissions and select "Access CRM Online as organization users" and click on Select.
Please note down the following to use in the Console Application
1) Client ID - Which is an Application ID of the App
2) Redirect URL - The one which we gave in Step 4 from above
Console Application
1) Create a Console Application.
2) Add Microsoft.IdentityModel.Clients.ActiveDirectory dll reference. If you don't have that, get it from Nuget Package.
Here the complete code which you can copy and paste and make sure you change the Global Variables accordingly.
Hope this helps.
--
Happy CRM'ing
I was hearing some requirement to connect to CRM Webapi from a console application. but never got a chance to really check. However, here are the steps that has to be foollwed and the code.
To connect CRM Web Api there are two steps.
1) Register the Application with the Azure Subscription
2) Build the Console Application to connect to CRM Web Api by using Client ID and Authority URL.
Just one thing to remember is the below process works if both CRM and Azure are under same tenant. If they are different tenant, we have to follow different process. Will try to write it next time.
Register the Application
1) Login to https://portal.azure.com and navigate to Azure Active Directory and click on New Application Registration button.
2) Enter the Name (whatever you wish). You can use any name which should be unique in the App Registrations.
3) Selecte Application Type as Native as we are not building any WebApplicaton/Web Api.
4) Next is Redirect URL. This is something, AD will redirect once the Authentication is done. You can put anything in the following format as we are calling this from Console Application.
XXXXXXX://XXXXXX
Note this URL as we need this in the Console Application
5) Click on the Create button to Register the App. Once the App is registred, you will get the Application ID.
6) Go to the settings of the app -> Required Permissions -> Add -> Select an API -> Dynamics CRM Online -> Select
7) And in the same place, click on Select Permissions and select "Access CRM Online as organization users" and click on Select.
Please note down the following to use in the Console Application
1) Client ID - Which is an Application ID of the App
2) Redirect URL - The one which we gave in Step 4 from above
Console Application
1) Create a Console Application.
2) Add Microsoft.IdentityModel.Clients.ActiveDirectory dll reference. If you don't have that, get it from Nuget Package.
Here the complete code which you can copy and paste and make sure you change the Global Variables accordingly.
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
namespace CRMWebApiConnection
{
classProgram
{
///<summary>
/// Holds the Authentication context based on the Authentication URL
///</summary>
staticAuthenticationContext authContext;
///<summary>
/// Holds the actual authentication token once after successful authentication
///</summary>
staticAuthenticationResult authToken;
///<summary>
/// This is the API data url which we will be using to automatically get the
/// a) Resource URL - nothing but the CRM url
/// b) Authority URL - the Microsoft Azure URL related to our organization on to which we actually authenticate against
///</summary>
staticstring apiUrl = "https://abc.crm5.dynamics.com/api/data";
///<summary>
/// Client ID or Application ID of the App registration in Azure
///</summary>
staticstring clientId = "ec014b98-af68-48fc-9147-7928420c08d7";
///<summary>
/// The Redirect URL which we defined during the App Registration
///</summary>
staticstringredirectUrl = "my-Console://CRMConsole";
staticvoid Main(string[] args)
{
GetToken();
Console.ReadLine();
}
internalstaticasyncvoid GetToken()
{
try
{
// Get the Resource Url & Authority Url using the Api method. This is the best way to get authority URL
// for any Azure service api.
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(newUri(apiUrl)).Result;
string resourceUrl = ap.Resource;
string authorityUrl = ap.Authority;
//Generate the Authority context .. For the sake of simplicity for the post, I haven't splitted these
// in to multiple methods. Ideally, you would want to use some sort of design pattern to generate the context and store
// till the end of the program.
authContext = newAuthenticationContext(authorityUrl, false);
try
{
//Check if we can get the authentication token w/o prompting for credentials.
//With this system will try to get the token from the cache if there is any, if it is not there then will throw error
// authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, new Uri(redirectUrl), new PlatformParameters(PromptBehavior.Never));
var userName = "XXXX@XXXX.onmicrosoft.com";
var password = "XXXXXXX";
UserCredential credentials = newUserPasswordCredential(userName, password);
authToken = awaitauthContext.AcquireTokenAsync(resourceUrl, clientId, credentials);
}
catch (AdalException e)
{
if (e.ErrorCode == "user_interaction_required")
{
// We are here means, there is no cached token, So get it from the service.
// You should see a prompt for User Id & Password at this place.
authToken = awaitauthContext.AcquireTokenAsync(resourceUrl, clientId, newUri(redirectUrl), newPlatformParameters(PromptBehavior.Auto));
}
else
{
throw;
}
}
Console.WriteLine("Got the authentication token, Retrieving data from Webapi");
GetData(authToken.AccessToken);
}
catch (Exception ex)
{
Console.WriteLine($"Please see the exception details : {ex.ToString()}");
}
}
internalstaticasyncvoid GetData(string token)
{
using (HttpClient httpClient = newHttpClient())
{
httpClient.Timeout = newTimeSpan(0, 2, 0); // 2 minutes time out period.
// Pass the Bearer token as part of request headers.
httpClient.DefaultRequestHeaders.Authorization =
newAuthenticationHeaderValue("Bearer", token);
var data = awaithttpClient.GetAsync("https://abc.crm5.dynamics.com/api/data/v8.2/accounts?$select=name");
if (data.StatusCode == System.Net.HttpStatusCode.OK)
{
// If the status code is success... then print the api output.
Console.WriteLine(await data.Content.ReadAsStringAsync());
}
else
{
// Failed .. ???
Console.WriteLine($"Some thing went wrong with the data retrieval. Error code : {data.StatusCode}");
}
Console.ReadLine();
}
}
}
}
--
Happy CRM'ing
Gopinath