This article was written by one of our Support Escalation Engineers Josh Wells.  I first would like to thank a support engineer from Kemp Technologies for really digging into this issue with me and collaborating together to identity the root cause and the solution documented below. Thanks Jim Schneider for your help and THANK YOU Kemp Technologies for the unbelievable support I received from your organization.

What’s the issue?

I recently had the pleasure of working with a customer trying to utilize a Kemp LoadMaster to handle the load balance requests of CRM. In addition, they wanted to accomplish SSL offloading as well. Finally, the customer wanted to use claims authentication so that their users could access CRM externally.

During their setup, they found that when SSL Acceleration (this is an option within Kemp LoadMaster), was enabled, they could not access the Service Endpoints of CRM. In a collaboration effort with Kemp, we were able to determine the root cause of the issue and how to fix it.

Explanation of the issue

The problem is that Kemp uses VIA headers rather than any sort of custom headers by default. VIA headers are explained in section 14.45 in the URL below:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Essentially what happens is that the URLs for the CRM requests are changed from the internal/external CRM Claims URLs to the FQDN (Fully Qualified Domain Name) of the server when the Kemp LoadMaster offloads the SSL certificate. Since the URL is being changed from the internal/external CRM claims URL to the FQDN of the server, CRM never sends the redirects the request to AD FS to capture a Claim because the URLs do not match what CRM is configured for.

Since we are not redirected to AD FS, the requests going to CRM are using the authentication method of Kerberos rather than passing over a claim. The problem we were running into was that CRM is expecting a Claim but none is being passed because we are using Kerberos authentication. If you capture a CRM platform trace, you will see something like the following:
[2012-10-29 11:46:22.287] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread: 15 |Category: Platform.Sdk |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: 8a1f8453-aac3-40f6-b434-8c066c225c56 | ServiceModelTraceRedirector.TraceData

<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error"><TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier><Description>Throwing an exception.</Description><AppDomain>/LM/W3SVC/2/ROOT-1-129959988004150063</AppDomain><Exception><ExceptionType>System.ServiceModel.FaultException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Access is denied.</Message><StackTrace>

So as you can tell, we are getting an access is denied error message. If we work our way back up the CRM platform trace, we can see that the claims being provided is null:

[2012-10-29 11:46:22.287] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread: 15 |Category: Platform.Sdk |User: 00000000-0000-0000-0000-000000000000 |Level: Info |ReqId: 8a1f8453-aac3-40f6-b434-8c066c225c56 | ServiceModelTraceRedirector.TraceData

<TraceRecord xmlns="http://schemas.microsoft.com/2009/10/IdentityModel/TraceRecord" Severity="Information"><Description>Authorize</Description><AppDomain>/LM/W3SVC/2/ROOT-1-129959988004150063</AppDomain><AuthorizeTraceRecord xmlns="http://schemas.microsoft.com/2009/06/IdentityModel/AuthorizeTraceRecord"><Authorize><Url>http://SERVER.FQDN/ORG/XRMServices/2011/OrganizationData.svc/</Url><Action>GET</Action><ClaimsPrincipal Identity.Name=""><ClaimsIdentity name=""></ClaimsIdentity></ClaimsPrincipal></Authorize></AuthorizeTraceRecord></TraceRecord>

If you analyze the message above further, notice the URL is set to http://SERVER.FQDN rather than http://internalcrm.FQDN. Since the URLs are different, we never are redirected to AD FS to capture a claim. Within a couple of elements of the trace event above, note that there is no claim with this request:

<ClaimsPrincipal Identity.Name=""><ClaimsIdentity name="">

This is a great explanation but how do we fix it?

Well we need Kemp to use a custom header that is going to be the same on every request. We can do that in Kemp in a couple of ways. You only need to use one of these two settings outline below. Note, instructions may vary with different versions of Kemp devices. These instructions were utilizing the Kemp LoadMaster version 6.0-38. If you are unable to determine how to setup your device properly, please contact Kemp support.

1. Modify Persistence

If you wish to use persistence, then the recommended Persistence option is Super HTTP. You can find more about this option on page 26 of the article found here:

http://www.kemptechnologies.com/fileadmin/content/downloads/documentation/6.0/KEMP_LoadMaster_Configuration_Guide.pdf

To accomplish this task using Persistence, follow the instructions below:

a. Access the Kemp web interface

b. Click on Virtual Services

c. Click on View/Modify Services

d. Locate the Virtual Services for CRM and click on Modify

e. Click on Standard Options

f. Next to Persistence Options, change it to Super HTTP

g. Click on Advanced Properties

h. On Add Header to request set it to the following:
FRONT-END-HTTPS:on

i. Click on Set Header

kemp1

2. Add a custom header

If you do not wish to use persistence, we can easily add a custom header to these requests. To do that follow these instructions:

a. Access the Kemp web interface

b. Click on Rules & Checking

c. Click on Content Rules

d. Click on Create New …

e. Set the following:
Rule Name: adfrontendheader
Rule Type: Add Header
Header Field to be Added: FRONT-END-HTTPS
Value of Header Field to be Added: on

kemp2

a. Click on Create Rule

b. Click on Virtual Services

c. Click on View/Modify Services

d. Locate the Virtual Services for CRM and click on Modify

e. Click on Advanced Properties

f. Click on Show Header Rules

g. Under Request Rules, change the drop down to “Add Header: addfrontendheader”

h. Click on Add

After you have one of the Custom Header options set within Kemp, now you need to access the Deployment Manager on the CRM server.

1. Within the Deployment Manager, click on Microsoft Dynamics CRM

2. On the right side of the Actions pane, click on Properties

3. Now click on Web Address

4. Click on Advanced

5. If you are using the load balancing option within Kemp, ensure you check “This deployment uses an NLB”

6. Under SSL Header, enter the following:
FRONT-END-HTTPS:on

7. Click OK > OK

kemp3

Now when accessing CRM, you should be properly redirected to the AD FS server and get a proper Claim. I hope this is helpful for those Kemp customers.