Refer: Part 1, Part 2, Part 2b, Part 3
In CRM 3.0 if you wanted to run an ASP.NET application on the same server as CRM (by CRM I mean the Web/App server) you needed to use your own application pool. This apps would then connect to CRM like an external application (see Part 3) if they needed to read/write data in CRM. For credentials these apps would simply use Integrated Windows Authentication - since a majority of customers used this configuration.
With the introduction of Internet Facing Deployment (IFD) which uses Forms Authentication for your Active Directory Credentials - this now means that developers cannot rely on Integrated Windows Authentication for their applications. It's important to recognize that all partner hosted customers will use IFD and most on-premise customers will configure their systems to use IFD + Windows Auth. As developers you must always consider IFD as a primary usage pattern for your applications.
Since IFD uses a Forms Authentication technology to collect your Active Directory credentials your own apps are faced with a problem. You can't use Integrated Windows Auth (as your app might be running outside the firewall where this auth type becomes very 'fragile') and you don't want to have to prompt the user for their credentials.
To cater for this situation we have provided a special class in the Microsoft.Sdk.dll called CrmImpersonator. This class allows an app which runs inside our context to use the credentials of the logged on user. When designing an app which runs on the CRM server you will need to observe some specific code patterns.
Here is the basic ASP.NET code behind which will create an new Lead when it opens and display the GUID of the record it created. The aspx and aspx.cs files will be placed on the CRM server in a folder called ISV. In a later post I'll cover off exactly how to deploy the solution. The Microsoft.Crm.Sdk and Microsoft.Crm.SdkTypeProxy namespaces derive from two DLLs of the same name. These DLLs are always present with CRM so you don't need to package them with your solution. You'll want to reference them in your project however and you'll find the DLLs in the \Server\GAC folder of your install files.
Let's examine the anatomy of this code pattern:
- You need to possess some pre-requisites: Page.Context, Organization Name and if you are using the Metadata Service you'll also need the MetadataService URL.
- All the CRM code is wrapped in in the using(new CrmImpersonator()) { } block.
- The CrmAuthenticationToken was created using the static method ExtractCrmAuthenticationToken of the CrmAuthenticationToken class.
- There is no need to use the Discovery Service. This code can only access the CRM Server which the code is running on.
- You must manually set the owner of objects using the CalledId property of the CrmAuthenticationToken.
I have a helper class which I use which provides me with the pre-requisites. I'll be cleaning this up in the next few weeks and I'll publish it for download and use (with a relatively free license).
In the next part we will examine using this technique in the offline client and in a later post we will examine the deployment considerations for this type of app.