Search code examples
wcfdynamics-crmwindows-authentication

CRM DiscoveryServiceProxy with windows authentication


We have a scenario where a WCF service is hosted on IIS. The authentication mode is WINDOWS. We are calling this WCF service from CRM plugin using windows authentication.

While getting the CRM organization instance, we are not getting windows user context.

private OrganizationDetail DiscoverOrganization(Uri discoveryUri, string organizationName, ClientCredentials lclClientCredentials)
        {
            DiscoveryServiceProxy serviceProxy;
            using (serviceProxy = new DiscoveryServiceProxy(discoveryUri, null, lclClientCredentials, null))
            {
                IDiscoveryService service = serviceProxy;
                var orgsRequest = new RetrieveOrganizationRequest()
                {
                    AccessType = EndpointAccessType.Default,
                    Release = OrganizationRelease.Current,
                    UniqueName = organizationName
                };
                var organizations = (RetrieveOrganizationResponse)service.Execute(orgsRequest);
                return organizations.Detail;
            }
        }

We tried setting credentials as below,

lclClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
                lclClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;

Solution

  • I don't think you can flow the Windows identity of the Dynamics client user to the web service this way. Dynamics plugins execute under one of three Windows accounts:

    • The account running the Sandbox service (for synchronous plugins registered in the plugin sandbox)
    • The account running the CRM web application pool (for synchronous plugins registered outside the sandbox)
    • The account running the Asynchronous service (for asynchronous plugins)

    On top of this is layered the Dynamics (systemuser) identity of the client user invoking the plugin, but not the Windows account. The Sandbox and Asynchronous services run in entirely separate processes from the web application, and likely have no way of knowing the Windows identity of the invoking user.


    If the web service needs the CRM identity of the invoking user (in order to act as that user in CRM), you will need to:

    • Pass the GUID of the client systemuser to the web service from the plugin.
    • Probably also pass some way to identify the CRM organisation to the web service from the plugin, assuming multiple orgs are in use in the deployment.
    • Authenticate to the web service using some other mechanism, e.g. Basic authentication, so that the service is still assured of being called only from the plugin.
    • Have the web service configured with connection details for all relevant CRM orgs (rather than use the Discovery service), including its own systemuser account in those orgs.
      • Edited to add: this could be configured as a non-interactive user, to save on licences.
    • Grant the web service's systemuser the Dynamics impersonation privilege, so it can act as other users.
    • When the web service is called:
      • Retrieve the appropriate connection details from configuration for the passed-in organisation.
      • Explicitly impersonate (using Dynamics impersonation) the passed-in systemuser GUID.