Search code examples
c#pluginsdynamics-365dynamics-crm-online

Dynamics CRM Plugin: Calling Web API with certificate in sandbox mode


trying to call an web API using client certificate in a plugin (D365 online) but i have this error "Permission request type 'System.Security.Permissions.KeyContainerPermission, mscorlib, Version=4.0.0.0, " (in this line X509Certificate2 certificate = new X509Certificate2(certificateBytes);) when i load the certificate and block me to get a response from the API also i tried to call this api from a console application and got a response this my code PS: my api use two authentification a certifcate and a basic user : if someone worked in this or have a solution please share it thanks

function callapi ()
try
{

  byte[] certificateBytes = Convert.FromBase64String(secretvalue);
  // Load the certificate from the byte array
  X509Certificate2 certificate = new X509Certificate2(certificateBytes);

  // Create an instance of HttpClientHandler
  HttpClientHandler handler = new HttpClientHandler();
  handler.ClientCertificateOptions = ClientCertificateOption.Manual;
  handler.ClientCertificates.Add(certificate);

  using (HttpClient httpClient = new HttpClient(handler))
  {
  
    // Set the Basic Authentication header
    var username = "user";
    var password = "password";
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")));

    // Convert the request body to JSON
    var jsonRequest = JsonConvert.SerializeObject(inputWS);
    var httpContent = new StringContent(jsonRequest, Encoding.UTF8, "application/json");

    // Make the API POST request
    HttpResponseMessage response1 = httpClient.PostAsync("webapilink", httpContent).Result;
    tracingService.Trace("response1", response1);
    if (response1.IsSuccessStatusCode){
      tracingService.Trace("successs", response1.StatusCode + response1.ReasonPhrase);

    }
    else {
      tracingService.Trace("failed", response1.StatusCode + response1.ReasonPhrase);

    }
    string responseContent = response1.Content.ReadAsStringAsync().Result;
    OutputWS responseRequest = JsonConvert.DeserializeObject<OutputWS>(responseContent);
    tracingService.Trace("responseRequest", responseRequest);


    tracingService.Trace("output function call", responseRequest);


    // Return the response content
    return responseRequest;

  }

}
catch (Exception ex)
{
  throw;
}

Solution

  • This error is probably related to plugins being executed in Sandbox isolation mode and the System.Security.Permissions namespace being historically problematic with partial-trust environments. The fact that your code works from a Console Application is a strong indication of this.

    Unfortunately, there's not much you can do without changing the API authentication or building a proxy for it.

    Please refer to Microsoft's recommendations for plugins accessing external web services.