Tuesday, 11 April 2017

CRM 2015 – Understanding impersonation in plugins and knowing when to use it

What is impersonation
When you create a plugin in CRM (step by step blog post here) you write an execute method which gets passed in
IServiceProvider serviceProvider
This has lots of variables and objects such as
  • IPluginExecutionContext
  • ITracingService
  • IOrganizationServiceFactory
You use the IOrganisationServiceFactory to create a IOrganizationService.  The IOrganizationService is the CRM SDK, it provides you access to CRM programmatically .  CRM developers use the IOrganizationService (which I will often call CRMService) to
  • CRUD operation – Create, Retrieve, Update, Delete records in CRM
  • Assign records
  • Change status
  • pretty much everything you can do in CRM
Here is the code to create the IOrganizationService, taken from the Plugin class of the CRM Dev toolkit
// Obtain the Organization Service factory service from the service provider
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);
When creating your plugin you will notice there is a Run in Context setting, most of the time you will choose to Run In Context of Calling User.
Create Account Plugin 1

99 percent of the time Calling User is the right choice

It’s usually the right choice to use the Calling User because any updates, retrieves or any interaction with CRM data will be done using the calling users identity and privileges.
If you visualize a plugin as an automated extension of the CRM form, it’s likely you want the the code in the plugin to run with security privileges as the calling user.  It allows you not to abdicate the need to apply security to the plugin code and pass this off the users security profile and CRM.
The PluginExecutionContext (which I explain in this blog post) has the field called UserId.  We pass this to the IOrganizationFactory to create an IOrganizationService with the user who initiated the plugin.  The good news is the CRM Dev toolkit does all this for us, so we can just chill out and get the IOrganizationService and work on the business logic.
// Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);
Running the CrmService (IOrganizationService) as the calling user means you are interacting with the data in CRM as the calling user, which means
  • The IOrganizationService can only retrieve data the user can retrieve
  • When IOrganizationService updates, creates records they are stamped with the calling user
  • The plugin cannot do anything the calling user cannot do
The calling user setting adheres to the security role assigned to the calling user, integrity of your precious CRM data is kept intact.

Why impersonate System User

If running plugins as the calling user is so good, why impersonate other users or system admins.
  • What if you need to retrieve records the user doesn’t have access to?
  • What if you need to update records the user doesn’t have access to?
You might be thinking, “if the user doesn’t have access to those records, maybe the plugin shouldn’t be updating them”.
It’s a point to consider point but sometimes you want to create records or update records based on the action/status of an entity to move the code to the next stage/state.
Sometimes you want to assign a record to another user when a record goes to a certain state but you wouldn’t want users to be able to assign records.

How is running in context different from impersonation

The running in context setting on a plugin mentioned early runs the whole plugin in that context.
Impersonation allows you to run a small section of code in another context.
Impersonation gives the CRM developer more flexibility to target a particular action in a plugin they would like to run with elevation permissions.  The rest of the plugin actions can be run as

Dangers of impersonation

The downsides of impersonation is it potentially gives users running the plugin\custom workflow enhanced security privileges which could lead who we don’t want updating\deleting records doing exactly that.
When using impersonation in plugins consider accountability and audit trails.  When a plugin impersonates a system user or a different user, the impersonated user will update those records.  It can be confusing/worrying for users when looking at audit records to see System Admin updating records.
I’m sure there have been thousands of support calls querying why System Admin has been updating records.

Impersonation Code

Easy way to impersonate System User is to pass null to the CreateOrganizationService and it will run as System user, find out more in this CRM SDK article
// Use the factory to generate the Organization Service.
OrganizationServiceImpersonated = factory.CreateOrganizationService(null);
You can pass in a different user Id to the CreateOrganizationService to create an IOrganizationService
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.InitiatingUserId);
The sample code in the CRM SDK article impersonates using OrganizationServiceContext.  I personally have used this
// Retrieve the system user ID of the user to impersonate.
OrganizationServiceContext orgContext = new OrganizationServiceContext(_serviceProxy);
_userId = (from user in orgContext.CreateQuery<SystemUser>()
where user.FullName == "Kevin Cook"
select user.SystemUserId.Value).FirstOrDefault();
// To impersonate another user, set the OrganizationServiceProxy.CallerId
// property to the ID of the other user.
_serviceProxy.CallerId = _userId;

Impersonating during plugin-in registration

You can impersonate a user during plugin-registration but I’m not entirely sure why you would do this, so I’m not going to talk about.  Most CRM developer will impersonate someone inside a plugin.
If you want to learn more read
and the articles in the futher reading section

Why, What, Where, When

What is Impersonation

Impersonation in plugins/custom workflows is creating an IOrganisationService as a different user

Why use Impersonation

Use impersonation when you need to update/retrieve/delete/Create records users security roles doesn’t let them.

Where

If you don’t want to increase users security roles but still want the plugin to do a particularly action.  e.g. delete a record


No comments:

Post a Comment