If you need to create a long running application to interact with the Microsoft CRM web services – for example, something to perform data migration or integration tasks – you need to be aware that, like all good things, web service connections do not last forever.

Note: the following uses example c# code and the CRM SDK libraries to connect to CRM Online.

First up, we need an instance of OrganizationServiceProxy. This can be created like so:

var uri = new Uri(string.Format("https://{0}.crm.dynamics.com/XRMServices/2011/Organization.svc", orgName));
var clientCredentials = new ClientCredentials();
clientCredentials.UserName.UserName = username;
clientCredentials.UserName.Password = password;
var deviceCredentials = DeviceIdManager.LoadOrRegisterDevice(); //from SDK: SampleCode\CS\HelperCode\DeviceIdManager.cs 
var organizationServiceProxy = new OrganizationServiceProxy(uri, null, clientCredentials, deviceCredentials);

Now, if you check the IsAuthenticated property on this, you will see that it is false. It is not until you actually use the service to do something that it actually gets authenticated. This lazy authenticating can be useful and saves some time when initialising the OrganizationServiceProxy object, as in the above sample. However, if you made a mistake with the credentials you won't actually know at this point, since it isn't until the authentication actually occurs that the provided credentials are checked. This could be an issue if you don't use the service straight away and don't want to wait until it is needed for you (or the end user of your application) to learn that the provided credentials are incorrect.

More importantly, it also means that when the first request is made there is an overhead to it, because it first has to authenticate and only then can it process the request. If you are creating an application that is waiting for user input or another service to call it, it may be better to take the hit straight up so you can then return responses as quickly as possible to the end user.

Thankfully, this is easily resolved: explicitly authenticate the service after creating it:

organizationServiceProxy.Authenticate();

So now we can get an authenticated connection but, getting back to my initial point, this will not stay so indefinitely. An authenticated OrganizationServiceProxy (against CRM Online at least), has a lifetime of 8 hours, and after this point any attempt to use it to communicate with CRM will result in security exceptions. This is easy enough to work around. Simply add a check before using it to check if the expiry time is coming up and if so call authenticate, which will take a little while, and then carry on with what you were doing.

Rather than trying to add this check before every request to the OrganizationServiceProxy, a better way to do this is to create a subclass of OrganizationServiceProxy and override ValidateAuthentication. This gets called before any other request gets processed, which allows you to write this check in one place and forget about. In this method we, simple add a check to see if the security token is about to expire and if so re-authenticate the service. Like so:

using System;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk.Client;

namespace Demo
{
    public class CrmService : OrganizationServiceProxy
    {
        public CrmService(Uri uri, Uri homeRealmUri, ClientCredentials clientCredentials, ClientCredentials deviceCredentials)
            : base(uri, homeRealmUri, clientCredentials, deviceCredentials)
        {
            Authenticate();
        }

        protected override void ValidateAuthentication()
        {
            EnsureAuthentication();
            base.ValidateAuthentication();
        }

        private void EnsureAuthentication()
        {
            if ((SecurityTokenResponse != null) &&
                (DateTime.UtcNow.Add(TimeSpan.FromMinutes(30)) >= SecurityTokenResponse.Response.Lifetime.Expires))
            {
                Authenticate();
            }
        }
    }
}

In the above example, I also added Authenticate() in the constructor so when you create a new instance of this it comes pre authenticated and you are good to go and use this exactly as you would the standard OrganizationServiceProxy.