From c12286993f36d0aecdf2c550631af398f901be2c Mon Sep 17 00:00:00 2001 From: MattB Date: Fri, 11 Jun 2021 12:23:16 -0700 Subject: [PATCH] Updated for Global Discovery Use. --- cds/App.config | 38 +-- .../DiscoveryService/DiscoveryService.csproj | 45 ++-- .../C#/DiscoveryService/SampleMethods.cs | 222 ++---------------- .../C#/DiscoveryService/SampleProgram.cs | 21 +- .../C#/DiscoveryService/packages.config | 15 +- 5 files changed, 85 insertions(+), 256 deletions(-) diff --git a/cds/App.config b/cds/App.config index 9c672837..27d90295 100644 --- a/cds/App.config +++ b/cds/App.config @@ -3,11 +3,11 @@ - - @@ -88,33 +88,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/cds/orgsvc/C#/DiscoveryService/DiscoveryService.csproj b/cds/orgsvc/C#/DiscoveryService/DiscoveryService.csproj index f45d919f..885d4c8b 100644 --- a/cds/orgsvc/C#/DiscoveryService/DiscoveryService.csproj +++ b/cds/orgsvc/C#/DiscoveryService/DiscoveryService.csproj @@ -35,52 +35,65 @@ - packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.4\lib\net452\Microsoft.Crm.Sdk.Proxy.dll + packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.34\lib\net462\Microsoft.Crm.Sdk.Proxy.dll packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll - - packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.2.4\lib\net452\Microsoft.Rest.ClientRuntime.dll + + packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.79\lib\net462\Microsoft.Rest.ClientRuntime.dll - packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.4\lib\net452\Microsoft.Xrm.Sdk.dll + packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.34\lib\net462\Microsoft.Xrm.Sdk.dll - packages\Microsoft.CrmSdk.Deployment.9.0.2.4\lib\net452\Microsoft.Xrm.Sdk.Deployment.dll + packages\Microsoft.CrmSdk.Deployment.9.0.2.34\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll - packages\Microsoft.CrmSdk.Workflow.9.0.2.4\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll + packages\Microsoft.CrmSdk.Workflow.9.0.2.34\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll - - packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.2.4\lib\net452\Microsoft.Xrm.Tooling.Connector.dll + + packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.79\lib\net462\Microsoft.Xrm.Tooling.Connector.dll - - packages\Microsoft.CrmSdk.XrmTooling.WpfControls.9.0.2.4\lib\net452\Microsoft.Xrm.Tooling.CrmConnectControl.dll + + packages\Microsoft.CrmSdk.XrmTooling.WpfControls.9.1.0.79\lib\net462\Microsoft.Xrm.Tooling.CrmConnectControl.dll - - packages\Microsoft.CrmSdk.XrmTooling.WpfControls.9.0.2.4\lib\net452\Microsoft.Xrm.Tooling.Ui.Styles.dll + + packages\Microsoft.CrmSdk.XrmTooling.WpfControls.9.1.0.79\lib\net462\Microsoft.Xrm.Tooling.Ui.Styles.dll - - packages\Microsoft.CrmSdk.XrmTooling.WpfControls.9.0.2.4\lib\net452\Microsoft.Xrm.Tooling.WebResourceUtility.dll + + packages\Microsoft.CrmSdk.XrmTooling.WpfControls.9.1.0.79\lib\net462\Microsoft.Xrm.Tooling.WebResourceUtility.dll - - packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + + packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + True + + packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll + + + packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + True + True + diff --git a/cds/orgsvc/C#/DiscoveryService/SampleMethods.cs b/cds/orgsvc/C#/DiscoveryService/SampleMethods.cs index 82935d33..53b33003 100644 --- a/cds/orgsvc/C#/DiscoveryService/SampleMethods.cs +++ b/cds/orgsvc/C#/DiscoveryService/SampleMethods.cs @@ -1,6 +1,7 @@ using Microsoft.IdentityModel.Clients.ActiveDirectory; using Microsoft.Xrm.Sdk.Discovery; using Microsoft.Xrm.Sdk.WebServiceClient; +using Microsoft.Xrm.Tooling.Connector; using System; using System.Collections.Generic; using System.ComponentModel; @@ -12,14 +13,6 @@ namespace PowerApps.Samples { public partial class SampleProgram { - - //These sample application registration values are available for all online instances. - public static string clientId = "51f81489-12ee-4a9e-aaae-a2591f45987d"; - public static string redirectUrl = "app://58145B91-0C36-4500-8554-080854F2AC97"; - - // version of ADAL that is linked to deal with diffrent version of ADAL. - private static Version _ADALAsmVersion; - /// /// Gets organization data for user in all regions when data center is unknown /// @@ -29,29 +22,13 @@ public partial class SampleProgram /// A List of OrganizationDetail records public static List GetAllOrganizations(string userName, string password, DataCenter dataCenter) { - var organizations = new List(); - - //If DataCenter.Unknown is used, loop through all known DataCenters + //If DataCenter.Unknown is used, Choose Commercial if (dataCenter == DataCenter.Unknown) { - foreach (DataCenter dc in (DataCenter[])Enum.GetValues(typeof(DataCenter))) - { - - if (dc != DataCenter.Unknown) - { - //Get the organization detail information for a specific region - List orgs = GetOrganizationsForDataCenter(userName, password, dc); - organizations = organizations.Concat(orgs).ToList(); - } - } - } - else - { - //When the data center is not unknown, get data from the specified region - organizations = GetOrganizationsForDataCenter(userName, password, dataCenter); + dataCenter = DataCenter.Commercial; } - - return organizations; + // Get data from Organization + return GetOrganizationsForDataCenter(userName, password, dataCenter); } /// @@ -73,159 +50,20 @@ public static List GetOrganizationsForDataCenter(string user var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); Uri targeturl = new Uri(((DescriptionAttribute)attributes[0]).Description); - var organizations = new List(); - - using (var dsvc = new DiscoveryWebProxyClient(targeturl)) - { - dsvc.HeaderToken = GetAccessToken(userName, password, targeturl); - - RetrieveOrganizationsRequest orgsRequest = new RetrieveOrganizationsRequest() - { - AccessType = EndpointAccessType.Default, - Release = OrganizationRelease.Current - }; - - try - { - RetrieveOrganizationsResponse response = (RetrieveOrganizationsResponse)dsvc.Execute(orgsRequest); - - organizations = response.Details.ToList(); - } - catch (System.ServiceModel.Security.SecurityAccessDeniedException) - { - //This error is expected for regions where the user has no organizations - } - - }; - return organizations; - } - - /// - /// Forming version tagged UriBuilder - /// - /// - /// - private static UriBuilder GetUriBuilderWithVersion(Uri discoveryServiceUri) - { - UriBuilder webUrlBuilder = new UriBuilder(discoveryServiceUri); - string webPath = "web"; - - if (!discoveryServiceUri.AbsolutePath.EndsWith(webPath)) - { - if (discoveryServiceUri.AbsolutePath.EndsWith("/")) - webUrlBuilder.Path = string.Concat(webUrlBuilder.Path, webPath); - else - webUrlBuilder.Path = string.Concat(webUrlBuilder.Path, "/", webPath); - } - - UriBuilder versionTaggedUriBuilder = new UriBuilder(webUrlBuilder.Uri); - string version = FileVersionInfo.GetVersionInfo(typeof(OrganizationWebProxyClient).Assembly.Location).FileVersion; - string versionQueryStringParameter = string.Format("SDKClientVersion={0}", version); - - if (string.IsNullOrEmpty(versionTaggedUriBuilder.Query)) - { - versionTaggedUriBuilder.Query = versionQueryStringParameter; - } - else if (!versionTaggedUriBuilder.Query.Contains("SDKClientVersion=")) - { - versionTaggedUriBuilder.Query = string.Format("{0}&{1}", versionTaggedUriBuilder.Query, versionQueryStringParameter); - } - - return versionTaggedUriBuilder; - } - - /// - /// Get the Authority and Support data from the requesting system using a sync call. - /// - /// Resource URL - /// Log tracer - /// Populated AuthenticationParameters or null - private static AuthenticationParameters GetAuthorityFromTargetService(Uri targetServiceUrl) - { - try - { - // if using ADAL > 4.x return.. // else remove oauth2/authorize from the authority - if (_ADALAsmVersion == null) - { - // initial setup to get the ADAL version - var AdalAsm = System.Reflection.Assembly.GetAssembly(typeof(IPlatformParameters)); - if (AdalAsm != null) - _ADALAsmVersion = AdalAsm.GetName().Version; - } - - AuthenticationParameters foundAuthority; - if (_ADALAsmVersion != null && _ADALAsmVersion >= Version.Parse("5.0.0.0")) - { - foundAuthority = CreateFromUrlAsync(targetServiceUrl); - } - else - { - foundAuthority = CreateFromResourceUrlAsync(targetServiceUrl); - } - - if (_ADALAsmVersion != null && _ADALAsmVersion > Version.Parse("4.0.0.0")) - { - foundAuthority.Authority = foundAuthority.Authority.Replace("oauth2/authorize", ""); - } + // Set up user credentials, + var creds = new System.ServiceModel.Description.ClientCredentials(); + creds.UserName.UserName = userName; + creds.UserName.Password = password; + Uri appReplyUri = new Uri(redirectUrl); - return foundAuthority; - } - catch (Exception ex) - { - throw (ex); - } - } - - /// - /// Creates authentication parameters from the address of the resource. - /// - /// Resource URL - /// AuthenticationParameters object containing authentication parameters - private static AuthenticationParameters CreateFromResourceUrlAsync(Uri targetServiceUrl) - { - var result = (Task)typeof(AuthenticationParameters) - .GetMethod("CreateFromResourceUrlAsync").Invoke(null, new[] { targetServiceUrl }); - return result.Result; - } + // Call to get organizations from global discovery. + var organizations = CrmServiceClient.DiscoverGlobalOrganizations( + targeturl, creds, null, clientId, appReplyUri, "", false, string.Empty, PromptBehavior.Auto); - /// - /// Creates authentication parameters from the address of the resource. - /// Invoked for ADAL 5+ which changed the method used to retrieve authentication parameters. - /// - /// Resource URL - /// AuthenticationParameters object containing authentication parameters - private static AuthenticationParameters CreateFromUrlAsync(Uri targetServiceUrl) - { - var result = (Task)typeof(AuthenticationParameters) - .GetMethod("CreateFromUrlAsync").Invoke(null, new[] { targetServiceUrl }); - return result.Result; + return organizations.ToList(); } - - public static string GetAccessToken(string userName, string password, Uri serviceRoot) - { - var targetServiceUrl = GetUriBuilderWithVersion(serviceRoot); - // Obtain the Azure Active Directory Authentication Library (ADAL) authentication context. - AuthenticationParameters ap = GetAuthorityFromTargetService(targetServiceUrl.Uri); - AuthenticationContext authContext = new AuthenticationContext(ap.Authority, false); - //Note that an Azure AD access token has finite lifetime, default expiration is 60 minutes. - AuthenticationResult authResult; - - if (userName != string.Empty && password != string.Empty) - { - - UserPasswordCredential cred = new UserPasswordCredential(userName, password); - authResult = authContext.AcquireTokenAsync(ap.Resource, clientId, cred).Result; - } - else - { - PlatformParameters platformParameters = new PlatformParameters(PromptBehavior.Auto); - authResult = authContext.AcquireTokenAsync(ap.Resource, clientId, new Uri(redirectUrl), platformParameters).Result; - } - - return authResult.AccessToken; - } } /// @@ -235,27 +73,15 @@ public enum DataCenter { [Description("Unknown")] Unknown, - [Description("https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc/web")] - NorthAmerica, - [Description("https://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc/web")] - SouthAmerica, - [Description("https://disco.crm3.dynamics.com/XRMServices/2011/Discovery.svc/web")] - Canada, - [Description("https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc/web")] - EMEA, - [Description("https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc/web")] - APAC, - [Description("https://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc/web")] - Oceania, - [Description("https://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc/web")] - Japan, - [Description("https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc/web")] - India, - [Description("https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc/web")] - NorthAmerica2, - [Description("https://disco.crm11.dynamics.com/XRMServices/2011/Discovery.svc/web")] - UK, - [Description("https://disco.crm12.dynamics.com/XRMServices/2011/Discovery.svc/web")] - France + [Description("https://globaldisco.crm.dynamics.com/api/discovery/v2.0/Instances")] + Commercial, + [Description("https://globaldisco.crm9.dynamics.com/api/discovery/v2.0/Instances")] + GCC, + [Description("https://globaldisco.crm.microsoftdynamics.us/api/discovery/v2.0/Instances")] + USG, + [Description("https://globaldisco.crm.appsplatform.us/api/discovery/v2.0/Instances")] + DOD, + [Description("https://globaldisco.crm.dynamics.cn/api/discovery/v2.0/Instances")] + CHINA } } diff --git a/cds/orgsvc/C#/DiscoveryService/SampleProgram.cs b/cds/orgsvc/C#/DiscoveryService/SampleProgram.cs index 007ad4de..1bb63530 100644 --- a/cds/orgsvc/C#/DiscoveryService/SampleProgram.cs +++ b/cds/orgsvc/C#/DiscoveryService/SampleProgram.cs @@ -7,8 +7,16 @@ namespace PowerApps.Samples { + /// + /// This sample has been updated work with PowerPlatform Online Only. + /// public partial class SampleProgram { + //These sample application registration values are available for all online instances. + public static string clientId = "51f81489-12ee-4a9e-aaae-a2591f45987d"; + public static string redirectUrl = "app://58145B91-0C36-4500-8554-080854F2AC97"; + + static void Main(string[] args) { string username = "yourUserName@yourOrgName.onmicrosoft.com"; @@ -36,11 +44,11 @@ static void Main(string[] args) { number++; - //Get the Organization Service URL - string fullOrgServiceUrl = o.Endpoints[EndpointType.OrganizationService]; + //Get the Organization Service URL + string fullOrgServiceUrl = o.Endpoints[EndpointType.OrganizationService]; - // Trim '/XRMServices/2011/Organization.svc' from the end. - string shortOrgServiceUrl = fullOrgServiceUrl.Substring(0, fullOrgServiceUrl.Length - 34); + // Trim '/XRMServices/2011/Organization.svc' from the end. + string shortOrgServiceUrl = fullOrgServiceUrl.Substring(0, fullOrgServiceUrl.Length - 34); Console.WriteLine("{0} Name: {1} URL: {2}", number, o.FriendlyName, shortOrgServiceUrl); }); @@ -60,10 +68,13 @@ static void Main(string[] args) //Use the selected serviceUrl with CrmServiceClient to get the UserId - string conn = $@"AuthType=Office365; + string conn = $@"AuthType=OAuth; Url={serviceUrl}; UserName={username}; Password={password}; + ClientId={clientId}; + RedirectUri={redirectUrl}; + Prompt=Auto; RequireNewInstance=True"; using (CrmServiceClient svc = new CrmServiceClient(conn)) diff --git a/cds/orgsvc/C#/DiscoveryService/packages.config b/cds/orgsvc/C#/DiscoveryService/packages.config index 8800d0d2..a538b142 100644 --- a/cds/orgsvc/C#/DiscoveryService/packages.config +++ b/cds/orgsvc/C#/DiscoveryService/packages.config @@ -1,16 +1,19 @@  - - - - - + + + + + - + + + +