1
votes

I am investigating impersonation in Microsoft Dynamics CRM 2016 / Dynamics 365 organization service and I found that the code is always executed on behalf of the system user (SYSTEM).

I created a plugin that should execute requests on behalf of different users:

  • system user (SYSTEM)
  • default user
  • user specified in the plugin registration tool
  • user initiating the request

But the code is always executed on behalf of the system user (SYSTEM).

I tried not only to display an exception, but also to create records - they are also created on behalf of the system user (SYSTEM).

public class GetUsers : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

        var result = "";

        var service1 = factory.CreateOrganizationService(null);
        result += $"null = {GetUserInfo(service1)}";

        var service2 = factory.CreateOrganizationService(Guid.Empty);
        result += $"Guid.Empty ({Guid.Empty}) = {GetUserInfo(service2)}";

        var service3 = factory.CreateOrganizationService(context.UserId);
        result += $"UserId ({context.UserId}) = {GetUserInfo(service3)}";

        var service4 = factory.CreateOrganizationService(context.InitiatingUserId);
        result += $"InitiatingUserId ({context.InitiatingUserId}) = {GetUserInfo(service4)}";

        throw new InvalidPluginExecutionException(result);
    }

    private static string GetUserInfo(IOrganizationService service)
    {
        var request = new WhoAmIRequest();
        var response = (WhoAmIResponse)service.Execute(request);
        var userId = response.UserId;
        var user = service.Retrieve("systemuser", userId, new ColumnSet("fullname"));
        var data = $"{userId} | {user.GetAttributeValue<string>("fullname")}{Environment.NewLine}";
        return data;
    }
}

I get this result:

null = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM
Guid.Empty (00000000-0000-0000-0000-000000000000) = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM
UserId (0a889533-cf85-e811-a21b-d47c6ef71c14) = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM
InitiatingUserId (c69c88fb-4e41-e811-a214-83daa2756e35) = 34248a5f-bf3e-4f3c-95c2-882424d25d37 | SYSTEM

All requests are executed on behalf of the system user, although they must on behalf of different users.

Previously (in CRM 4.0-2013) it worked, but now it does not work. I tried on two different systems (different versions) - the result is the same.

Why?

1
This article talks about impersonation, but does not answer the question why all requests are executed on behalf of SYSTEM.Roman Kopaev

1 Answers

0
votes

Your example executes the WhoAmI request on behalf of several identities, but WhoAmI always returns the systemuserid of the authenticated user and since plugins are being executed by the SYSTEM account, its ID will always be returned.

Execute e.g. a Create request on entity Account and examine the attributes CreatedBy, CreatedOnBehalf and OwnerId.