0
votes

I need to make a request to an azure function http endpoint from dynamics crm. The crm is an on-premise 2016 instance. I would like to do this in a custom workflow/action, since there are a few different places I want to trigger the action (manual, from a web resource, from other C# code), which involves doing some processing and then sending data to the function.

The part of the code making this call looks something like this (simplified);

// In Setup
client = new HttpClient();

// In the main action, after some processing
PostMessage(data).Wait();

// Defined seperately
private async Task PostMessage(string message) {
  var response = await client.PostAsync(functionUrl, message);
  response.EnsureSuccessStatusCode();
}

The functionUrl above looks something like https://namespace.azurewebsites.net/api/name?code=key (with appropriate substitions).

When this code runs, I get a security exception. The message does not seem helpful, but I have reproduced it below. I have managed to confirm that it is definitely being thrown by the await client.PostAsync(functionUrl, message) line.

I have tested using the same code with a different url - in particular the azureOathUrl (https://login.microsoftonline.com/common/oauth2/token), because I make requests to that in another workflow on this CRM - and that did not throw a security exception.

How do I make a request to an azure function work? Is there something specific I need to do to connect to certain urls (I've not seen any references for this)?

Security exception thrown;

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Security.SecurityException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #2E606488Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ActivityId>48ed9d3c-bd82-4e65-b65f-c3c75501137e</ActivityId>
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>System.Security.SecurityException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #2E606488</Message>
<Timestamp>2019-09-16T13:44:30.7417027Z</Timestamp>
<ExceptionRetriable>false</ExceptionRetriable>
<ExceptionSource>PluginExecution</ExceptionSource>
<InnerFault i:nil="true" />
<OriginalException>System.Security.SecurityException
at System.ComponentModel.Win32Exception.GetObjectData(SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj, String&amp; typeName, String&amp; assemName, String[]&amp; fieldNames, Object[]&amp; fieldValues)


at Microsoft.Crm.Sandbox.SandboxAppDomainHelper.Execute(IOrganizationServiceFactory organizationServiceFactory, String customActivityTypeName, IExecutionContext requestContext, Dictionary`2 sandboxServices, Boolean useDrawbridgeEnabled, Boolean chaosFailAppDomain)
at Microsoft.Crm.Sandbox.SandboxWorker.ExecuteCustomWorkflowActivity(SandboxCallInfo callInfo, SandboxCustomActivityExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, SandboxRequestCounter&amp; workerCounter, Boolean returnTraceInfo)</OriginalException>
<TraceText i:nil="true" />
</OrganizationServiceFault>

Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.Crm.Sandbox.ISandboxHost.ExecuteCustomWorkflowActivityAndReturnTraceInfo(SandboxCallInfo callInfo, SandboxCustomActivityExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String assemblyContents, Boolean returnTraceInfo)
at Microsoft.Crm.Sandbox.SandboxCustomActivity.Execute(SandboxClient client, SandboxCallTracker callTracker, IExecutionContext requestContext, String assemblyContents, Boolean returnTraceInfo)
at Microsoft.Crm.Sandbox.SandboxCodeUnit.Execute(IExecutionContext context)
1
quick question, Can You reach Internet Web from your CRM User, what I mean is CRM Plugins runs under Service Account user IIS user in my case user it is crmtestappserv I had similar issue on one of my onPrem CRM 2016. Issue was this user when tried to reach internet did not have rights and hence was failing. Plugins and Workflow Assembly runs under this user in CRM.AnkUser
I've got another workflow that makes requests to login.microsoftonline.com, which works (and I've tested that url in this code too), so I'm pretty sure it's able to reach the internet.meta

1 Answers

0
votes

I have a few thoughts that might help.

First, be careful newing up an HttpClient every time. If you get enough traffic, this can lead to socket exhaustion. (Learned that the hard way.)

Second, are you setting your TLS to 1.2 by doing this? System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

I found a lot of calls will fail if you don't specific TLS1.2 and if I recall correctly, Azure Functions is one that requires 1.2.

Third, do you have any firewalls or security for your Azure Function yet? You might be getting an unauthorized call.