Breaking news from around the world
Get the Bing + MSN extension
Now Available in Community - MBAS 2019 Presentation Videos
Catch the most popular sessions on demand and learn how Dynamics 365, Power BI, PowerApps, Microsoft Flow, and Excel are powering major transformations around the globe. | View Gallery
2019 release wave 2 Discover the latest updates to Dynamics 365Release overview guides and videos Release Plan | Early Access Availability
Ace your Dynamics 365 deployment with packaged services delivered by expert consultants. | Explore service offerings
Connect with the ISV success team on the latest roadmap, developer tool for AppSource certification, and ISV community engagements | ISV self-service portal
The FastTrack program is designed to help you accelerate your Dynamics 365 deployment with confidence.
FastTrack Program | Finance TechTalks | Customer Engagement TechTalks | Talent TechTalks | Upcoming TechTalks
Plugins are usually set to run as the calling user but sometimes you need to run a plugin with System User privileges.
Before I explain how, we should first look at the why and how you impersonate users inside a plugin
I have been writing a bit about plugins recently
For some step by step guides to creating plugins check out the CRM Code examples section on the page Hosk’s CRM Developer Articles, I created some Youtube videos CRM 2013 Plugins
When you create a plugin in CRM (step by step blog post here) you write an execute method which gets passed in
This has lots of variables and objects such as
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
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.
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.
Running the CrmService (IOrganizationService) as the calling user means you are interacting with the data in CRM as the calling user, which means
The calling user setting adheres to the security role assigned to the calling user, integrity of your precious CRM data is kept intact.
If running plugins as the calling user is so good, why impersonate other users or system admins.
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.
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
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.
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
Sample: Impersonate using the ActOnBehalfOf privilege
// 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"
// To impersonate another user, set the OrganizationServiceProxy.CallerId
// property to the ID of the other user.
_serviceProxy.CallerId = _userId;
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
Impersonate another user
and the articles in the futher reading section
Impersonation in plugins/custom workflows is creating an IOrganisationService as a different user
Use impersonation when you need to update/retrieve/delete/Create records users security roles doesn’t let them.
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
You use impersonation in plugins/customer workflows
Scott Durow has an excellent article on Impersonation
User Impersonation in Plugins, Workflow and Dialogs
CRM SDK 2015 impersonating User in plugins
Dave Berry does a good job explaining Impersonation – CRM Impersonation Explained
Awesome Pixar impersonation picture from here
Business Applications communities