locked
Using AD authentication from external ASP.NET application to CRM WebService RRS feed

  • Question

  • I'm having a whole bunch of trouble with this so any help would be greatly appreciated....

    BTW - I am no pro at this so if any of my description seems a bit off - I appologize.

    I am developing an ASP.NET application to do some updating of CRM entities.  The crm installation is on-premise and uses AD authentication with IFD enabled. The ASP.NET app will reside on a separate webserver with anonymous authentication disabled. The separate webserver and the CRM are on the same domain. When the user accesses the ASP.NET app, he is prompted for his Windows credentials and is able to log in. I then want those same credentials to be used to access the CRM webservice to perform the updates to the CRM records.  I have read countless posts on similar scenarios but I have not yet been able to get my app to work.  I am always getting some sort of authentication error when trying to call the update method of the CRM service.

    Here is the current code segment that I have (uses SDK Assembly):

                        CrmAuthenticationToken authToken = new CrmAuthenticationToken();
                        authToken.AuthenticationType = 0;
                        authToken.OrganizationName = "Orgname";                   
                       
                        crmService = new CrmService();
                        crmService.Url = "http://crm:5555/mscrmservices/2007/crmservice.asmx";

                        crmService.CrmAuthenticationTokenValue = authToken;
                                           
                        crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
                                           
                        task crmTask = new task();
                        crmTask.activityid = taskID;
                        crmTask.description = "Test";

                        crmService.Update(crmTask);  

    taskID is the Key value of an existing CRM Task that belongs to me.  When I execute this from my development workstation it works fine.  But when I deploy it to the webserver and log in using my same credentials, the Update call results in:

    The request failed with HTTP status 401: Unauthorized.

    Again - I have tried many different approaches to this and all have failed for one reason or another.  Can someone please help me find the proper way to accomplish this?

    Thank you in advance. 

     

    Friday, December 31, 2010 4:51 PM

Answers

  • The standard way to fulfill your requirements you'll need to enable delegation with Active Directory. This is necessary for the user's AD credentials to be passed by the server that hosts your custom page to the CRM server. See http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx for a decent overview of this.

    If you can't enable delegation, then the following should work:

    • Put your asp .net page in an application pool that has an identity of a Crm user that is also a member of the AD group PrivUserGroup.
    • Enable AD impersonation
    • In your code, get the AD account of the user submitting the request - you can get this from User.Identity.Name
    • You then need to revert the security context back to that of the application pool. The 'using new CrmImpersonator()' block should do this for you, otherwise see http://support.microsoft.com/kb/306158 for an example of how to do this yourself
    • Then retrieve the systemuserid of the Crm user with the logon name you got earlier, and put that into the CallerId property of the CrmAuthenticationToken

    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    • Marked as answer by arcy67 Wednesday, January 5, 2011 9:34 PM
    Tuesday, January 4, 2011 11:59 AM
    Moderator
  • Asuming the organisation name and url are correct, then your code should be fine. No code changes should be required to use delegation compared to impersonation.

    For delegation to work you'll need to have SPNs setup correctly, and also check that IIS on the server that hosts your custom page uses Kerberos (aka Negotiate) rather than NTLM. I'd expect some Kerberos errors in the system (I think) event log if delegation is not setup correctly

     


    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    • Marked as answer by arcy67 Wednesday, January 5, 2011 9:34 PM
    Tuesday, January 4, 2011 6:03 PM
    Moderator

All replies

  • I guess the problem is that your ASP.NET page is calling CRM with the AppPool user not with the user which is calling your page (because ASPX site is in a different server than CRM). I think you have some alternatives:

    Option 1. Put your ASPX page in the CRM server (ISV folder) then it will run under the CRM context
    Option 2. Impersonate the code which calls CRM service (with CRMImpersonator)
    Option 3. Use a user on crmService.Credentials

    Each option has its own pro and cons.

    Regards,


    Albert Porra
    Friday, December 31, 2010 6:56 PM
  • Thank you for the reply Albert.

    Unfortunately I don't think any of those options are going to work for me. 

    1. The asp.net page must reside on a separate server so it cannot run under the CRM Context. 
    2. It is my understanding that the CRMImpersonator Class only works when running under the CRM Context.
    3. Hard coding a single user for all wed service calls won't work as we need to see what updates were made by what user. 

     

    Friday, December 31, 2010 8:20 PM
  • The standard way to fulfill your requirements you'll need to enable delegation with Active Directory. This is necessary for the user's AD credentials to be passed by the server that hosts your custom page to the CRM server. See http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx for a decent overview of this.

    If you can't enable delegation, then the following should work:

    • Put your asp .net page in an application pool that has an identity of a Crm user that is also a member of the AD group PrivUserGroup.
    • Enable AD impersonation
    • In your code, get the AD account of the user submitting the request - you can get this from User.Identity.Name
    • You then need to revert the security context back to that of the application pool. The 'using new CrmImpersonator()' block should do this for you, otherwise see http://support.microsoft.com/kb/306158 for an example of how to do this yourself
    • Then retrieve the systemuserid of the Crm user with the logon name you got earlier, and put that into the CallerId property of the CrmAuthenticationToken

    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    • Marked as answer by arcy67 Wednesday, January 5, 2011 9:34 PM
    Tuesday, January 4, 2011 11:59 AM
    Moderator
  • Hi David -

    Thank you for the reply.  I thought I had delegation enabled but I may be missing something. I will look into it further and consult our network guy.

    In the meantime could you let me know if the above code is correct for the delegation scenario?

    Tuesday, January 4, 2011 4:49 PM
  • Asuming the organisation name and url are correct, then your code should be fine. No code changes should be required to use delegation compared to impersonation.

    For delegation to work you'll need to have SPNs setup correctly, and also check that IIS on the server that hosts your custom page uses Kerberos (aka Negotiate) rather than NTLM. I'd expect some Kerberos errors in the system (I think) event log if delegation is not setup correctly

     


    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    • Marked as answer by arcy67 Wednesday, January 5, 2011 9:34 PM
    Tuesday, January 4, 2011 6:03 PM
    Moderator
  • I finally got this working using delegation.  David - I can't thank you enough.  Your advice and the delegation article you referenced were extremely helpful. 

    Turns out I had 2 issues...

    First the SPN on the webserver was incorrect and second I needed to add the web URL to the Trusted Sites in IE.

    Thanks again.

    Wednesday, January 5, 2011 9:33 PM