user781961
user781961

Reputation: 21

Using Windows Credentials to instantiate OrganizationServiceProxy in CRM 2011

Has anybody tried to use the Windows credentials to create an instance of OrganizationServiceProxy in CRM 2011 (On-Premise) ? I have a WCF service that uses

      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows"/>
      </security>

and I am able to confirm that the user is authenticated (OperationContext.Current.ServiceSecurityContext.WindowsIdentity.IsAuthenticated) but I don't know how to generate/pass the ClientCredentials to create an instance of the CRM service. This is called from a Silverlight application that does not live in an IFrame inside CRM.

Thanks.

Upvotes: 0

Views: 2197

Answers (1)

Rustin
Rustin

Reputation: 89

What you need to use separate user account to log into the OrganizationServiceProxy. You wont be able retrieve the windows credentials to pass to the proxy for authentication.

The user that you do use needs prvActOnBehalfOfAnotherUser privilege associated with it.

Once this is done and you can successfullly login and retrieve a valid OrganizationServiceProxy, what you need to do as a consumer of the service is specify the CallerId whenever you are calling operations on it. This token you should retrieve from the xrm model using Xrm.Page.context.getUserId. See. http://msdn.microsoft.com/en-us/library/gg334511.aspx.

Then from silverlight you would use the System.Windows.Browser.ScriptObject bridge to execute client side javascript to retrieve the userid of current user logged into crm. Preferably do this at application bootstrap time and save the value into an applicationdata variable so so can access it globally from within your silverlight app.

Eg. of client side script.

function CrmContext() {
}

var context = null;
with (window.parent) {
    context = Xrm.Page.context;}

CrmContext.prototype.ReadUserId = function () {
   var userId = context.getUserId();
   return userId;
}

Once you have the user token set the Proxy CallerId with this value

Eg.

private OrganizationServiceProxy Proxy { get; set; }

public Guid Create(CreateEntity request)
{
    if (request == null || request.UserId == Guid.Empty || request.Entity == null)
    {
        throw new InvalidMessageException("Invalid reqest message. Please provide compulsory criteria");
    }

    var result = Guid.Empty;

    try
    {
        if (Proxy != null)
        {
            Proxy.CallerId = request.UserId;

            using (Proxy)
            {
                result = Proxy.Create(request.Entity);
            }
        }
    }
    catch (FaultException<OrganizationServiceFault> e)
    {
        Log.Error(e.Message);
        throw new IntegrationException(e.Message);
    }

    return result;
}

The approach ive taken to solve this was to create a crm adapter encapsulating the crm proxy and sending request object to service interface that includes the user token.

public OrganizationServiceAdapter(ICrmConfigurationContext crmConfigurationConext)
{
    try
    {
        Proxy = new OrganizationServiceProxy(
            crmConfigurationConext.OrganizationServiceConfiguration,
            crmConfigurationConext.Credentials);
    }
    catch (Exception e)
    {
        //// TODO: Add local proxy pattern implementation for failover
        Proxy = null;
        Log.Error(e.Message);
        throw new IntegrationException(ExceptionMessages.CouldNotLoginToOrganizationService());
    }
}

Upvotes: 1

Related Questions