locked
Understanding impersonation in MS CRM RRS feed

  • Question

  • Hi All,

    Can any one clearly explain the use of 'new CrmImpersonator()' with an example? I have been going through many articles but unable to clearly understand the purpose of it.

    And also please elaborate the line 'Impersonation is the ability of a thread to execute using different security information than the process that owns the thread.' - hard to digest :(

     

    Many Thanks

    Wednesday, February 23, 2011 2:21 PM

Answers

  • Probably the best place to start is that there are sets of communication:

    1. The end user accessing a page containing your code (which is in the CRM web site)
    2. Your code then connects to the CrmService

    In step 1, the end user will be authenticated by CRM. This could use either IFD or AD authentication. In step 2, when your code connects to the CrmService it will always use AD authentication. Continuing step 2, the AD credentials used for the connection need to be recognised by the CRM platform as those of a CRM user (which includes the SYSTEM user). If the CallerId property of the CrmAuthentication token is set to the systemuserid of a CRM user, then the actions performed on the platform will be done on behalf of this impersonated CRM user. This is only permitted to work if the AD credentials belong to the AD group PrivUserGroup. To summarise (and answer your last question) when impersonating the credentials of the CrmService must be the AD credentials of an account that is a member of PrivUserGroup, and the user to impersonate is identified by the CallerId property of the CrmAuthentication token

    In your code above, the line that uses ExtractCrmAuthenticationToken is correct, as is your summary. One point to add is that the CrmAuthenticationToken also specifies that AD authentication will be used to connect to the platform.

    Then you need to ensure the AD credentials used to connect to CrmService belong to a member of PrivUserGroup. This can be done in one of 2 ways:

    1. You explicitly create a new NetworkCredential, as per your next line of code. If you do this, then CrmImpersonator is unnecessary
    2. You use CredentialCache.DefaultCredentials, which are the AD credentials the code is running under; i.e. the security context of the thread. The fun bit is that ASP .Net impersonation is used for internal users who connect to your code via AD, and not IFD, so the thread would be set to that user, who should not be a member of PrivUserGroup. To prevent problems with this, you wrap your code within an instance of the CrmImpersonator class. The constructor of CrmImpersonator reverts the thread's security context to that of the process, which is the identity of the application pool and should be a member of PrivUserGroup. For completeness the destructor of CrmImpersonator reapplies the user's security context to the thread

    So, if you create a new NetworkCredential, then you don't need CrmImpersonator, and conversely if you use CrmImpersonator then you don't need to create a new NetwrokCredential. I always go for the latter as I don't like storing user names and passwords (which you need to do if you create a new NetworkCredential)


    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    Thursday, February 24, 2011 9:01 AM
    Moderator

All replies

  • The quote above 'Impersonation is the ability of a thread to execute using different security information than the process that owns the thread' refers to one type of impersonation, and is probably not the best place to start. The reason I suggest that it is not a good place to start is that, although it summarises what happens with standard impersonation of Active Directory credentials in an ASP .Net application, impersonation in CRM works in a different way.

    A short explanation of impersonation in this scenario is that the ExtractCrmAuthenticationToken method will provide CRM impersonation by setting the CallerId property of the CrmAuthenticationToken to the systemuserid of the impersonated user (described in http://msdn.microsoft.com/en-us/library/cc151052.aspx). The sole purpose of the CrmImpersonator class is to ensure the code runs under the AD context of the application pool identity, which is a member of the AD PrivUserGroup, and hence is permitted to perform CRM impersonation.

    There's more detail that could be described, but I'm not sure how much that would help unless you have a good grasp of AD impersonation in ASP .Net

     

     


    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    Wednesday, February 23, 2011 9:07 PM
    Moderator
  • Hi David,

    Thanks for this.

    I have worked a lot on impersonation with respect to Asp.Net applications. But the CRM part seems to be very confusing.

    Let me use some code snippets to understand this further.

     

     

    CrmAuthenticationToken token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, Organisation);

    The above code will set the authentication token to the user who is using the CRM (logged in using IFD or AD). So this is the user who is being Impersonated.

     

     

    crmService.Credentials = new NetworkCredential("PrivUserName","PrivUserPassword","PrivUserDomain")

    This code will set the credentials to the priviliged user who has the right to perform the impersonation. So this user is the one who is doing Impersonation, hence Impersonating user.

     

    So, what is the use of the 'new CrmImpersonator()'. We place all the code in the using block of 'new CrmImpersonator()'. What does this signify?

    And also what is the difference between the authenticationtoken and the credentials of CRMService.

    Many have this confusion, so i am just trying to understand this a bit clearly.

    Thanks

    Thursday, February 24, 2011 7:30 AM
  • Probably the best place to start is that there are sets of communication:

    1. The end user accessing a page containing your code (which is in the CRM web site)
    2. Your code then connects to the CrmService

    In step 1, the end user will be authenticated by CRM. This could use either IFD or AD authentication. In step 2, when your code connects to the CrmService it will always use AD authentication. Continuing step 2, the AD credentials used for the connection need to be recognised by the CRM platform as those of a CRM user (which includes the SYSTEM user). If the CallerId property of the CrmAuthentication token is set to the systemuserid of a CRM user, then the actions performed on the platform will be done on behalf of this impersonated CRM user. This is only permitted to work if the AD credentials belong to the AD group PrivUserGroup. To summarise (and answer your last question) when impersonating the credentials of the CrmService must be the AD credentials of an account that is a member of PrivUserGroup, and the user to impersonate is identified by the CallerId property of the CrmAuthentication token

    In your code above, the line that uses ExtractCrmAuthenticationToken is correct, as is your summary. One point to add is that the CrmAuthenticationToken also specifies that AD authentication will be used to connect to the platform.

    Then you need to ensure the AD credentials used to connect to CrmService belong to a member of PrivUserGroup. This can be done in one of 2 ways:

    1. You explicitly create a new NetworkCredential, as per your next line of code. If you do this, then CrmImpersonator is unnecessary
    2. You use CredentialCache.DefaultCredentials, which are the AD credentials the code is running under; i.e. the security context of the thread. The fun bit is that ASP .Net impersonation is used for internal users who connect to your code via AD, and not IFD, so the thread would be set to that user, who should not be a member of PrivUserGroup. To prevent problems with this, you wrap your code within an instance of the CrmImpersonator class. The constructor of CrmImpersonator reverts the thread's security context to that of the process, which is the identity of the application pool and should be a member of PrivUserGroup. For completeness the destructor of CrmImpersonator reapplies the user's security context to the thread

    So, if you create a new NetworkCredential, then you don't need CrmImpersonator, and conversely if you use CrmImpersonator then you don't need to create a new NetwrokCredential. I always go for the latter as I don't like storing user names and passwords (which you need to do if you create a new NetworkCredential)


    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
    Thursday, February 24, 2011 9:01 AM
    Moderator
  • David, thanks for the detailed explanation. Now it very much clear. (i will read this content daily for next 1 week to remember forever :) ).

     

    Its basically the Impersonation is enabled for complete CRM application by setting <identity impersonate="true" /> in the web.config.

    Using 'new CRMImpersonator()' we are telling that the code to be executed with the identity mentioned in

    Application pool.

    That was great stuff.


    Thursday, February 24, 2011 11:25 AM