I have been working on a project for the last 5 months - integrating one of our older systems to use Dynamics365 CRM to store and record leads for our marketing and sales department.
Everything works as it should on several environments - we have a DEV, Sandbox as well as TEST and my local machine. It works everywhere except the UAT server which is hosted in completely different city as opposed to the others which are in the building we work in.
We have made sure TSL 1.2 is used and application forces this in code. Compared .NET Features on all machines and they're exactly the same, ciphers and configuration files are nearly the same, the differences are minor such as connection strings for our databases.
We are connecting to the same instance of CRM across all environments.
The project has been compiled using .NET 4.6.1
Microsoft.CrmSdk.CoreAssemblies - 9.0.2.4
Microsoft.CrmSdk.XrmTooling.CoreAssembly - 9.0.2.7
Microsoft.IdentityModel.Clients.ActiveDirectory - 2.22.302111727
Our Azure (we use AD to login to CRM via C#) has no whitelist.
Dynamics as far as we know has no whitelist.
There is no firewall rule that blocks any outgoing connections on 443 port so everything resembles other environments yet we receive "Unable to login to Dynamics CRM" error message.
This is the code we use to connect to CRM..
string Thumbprint = ConfigurationManager.AppSettings["CertThumbprint"];
string adInstance = ConfigurationManager.AppSettings["ADInstance"];
string adTenant = ConfigurationManager.AppSettings["Tenant"];
string Url = ConfigurationManager.AppSettings["Application"];
string AppId = ConfigurationManager.AppSettings["ClientId"];
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection CertificateCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, Thumbprint, false);
if (CertificateCollection.Count == 0)
throw new Exception("Error: Could not find the right certificate.");
X509Certificate2 AzureCertificate = CertificateCollection[0];
CrmServiceClient.AuthOverrideHook = new AuthHook(adInstance, adTenant, Url, AppId, AzureCertificate);
var crmSvc = new CrmServiceClient(new Uri(Url), true);
if (crmSvc == null || !crmSvc.IsReady) throw new Exception(crmSvc == null ? "CrmServiceClient Failure." : crmSvc.LastCrmException.ToString());
this.service = (IOrganizationService)crmSvc.OrganizationWebProxyClient ?? crmSvc.OrganizationServiceProxy;
This line specifically returns the error and also is set as null...
var crmSvc = new CrmServiceClient(new Uri(Url), true);
Worth mentioning the only difference between UAT compared to the rest is that UAT is running on .NET 4.7.1 compared to the others runing .NET 4.7.2.
If anyone came across this one it would be highly appreciated or any ideas what it could be.
Edit: I have just tried putting a fallback method that authenticates using Office365 to no avail. Same error... this method has worked on every other environment.
The code used was:
ClientCredentials clientCredentials = new ClientCredentials();
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["crm_user"]) &&
!string.IsNullOrEmpty(ConfigurationManager.AppSettings["crm_password"]))
{
clientCredentials.UserName.UserName = ConfigurationManager.AppSettings["crm_user"];
clientCredentials.UserName.Password = ConfigurationManager.AppSettings["crm_password"];
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
this.service = (IOrganizationService)new OrganizationServiceProxy(new Uri(ConfigurationManager.AppSettings["crm_org_url"]),
null, clientCredentials, null);
if (this.service == null)
{
Exception e = new Exception("CRM: Could not login to organization service proxy.");
throw e;
}
}
else
{
throw new Exception("CRM: Could not connect using a fallback method. The web configuration doesn't contain crm_user or crm_password keys.");
}