RunAs in FIM 2010

Often times, I come across the question

How can I write some code to do something as another user in FIM 2010?

Generally I see two different answers:

  1. Impersonate the other user
  2. Set the ActorId to the user

So which one is correct?

In fact, both can be correct, depending on what you are trying to do.

How does FIM work?

To understand which approach you should use, you have to understand how FIM works.

FIMService exposes different WebService endpoints for differetn Create / Read / Update / Delete / Enumerate / etc operations. Those endpoints have a binding that requires Kerberos. When an EXE running as DomainA\JohnDoe makes a WebService call to FIMService, FIMService will look at the WindowsIdentity of the caller and first thing it does is creating a Request Object with Requestor stamped as the calling user (JohnDoe in this case). This is pretty much a few of the only place where FIMService is looking at the WindowsIdentity. From then on, FIMService will follow the request processing pipeline based on the Request Object.

Now consider an ASP.NET application (imagine a FIMPortal clone) is running as DomainA\PortalServiceAccount which provides a front-end UX for Group Management. When JohnDoe goes to the portal, the ASP.NET app should really be making the WebService call as JohnDoe (instead of PortalServiceAccount) so the rights / permissions applies. In this case, it is not hard to imagine that ASP.NET code should impersonate JohnDoe and make the WebService call to FIMService. This is answer #1.

After the Request Object is created with proper Requestor stamped, FIMService executes the request processing pipeline under its own credential (i.e. FIMService service account). FIMService does NOT impersonate the user. That's partly because FIMService manages its own rights / permissions using Management Policy Rule (MPR). FIMService does NOT rely on Active Directory's permission infrastructure.

As part of the request processing pipeline, FIMService will run different Workflows and Activities. Since FIMService does NOT impersonate the Requestor, it is FIMService service account that is executing the code as far as .NET and OS can tell. Now, in the Activity code, if you want to do something as JohnDoe, you will set the ActorId to JohnDoe. This is answer #2.

Base line is that:

  • Kerberos is an Active Directory construct and it's the way to let FIMService knows who is making the WebService call. A client application running as UserA can impersonate as UserB when making the WebService call so the Requestor would become UserB. If you are writing a custom client to consume FIMService's WebService endpoints, you should impersonate.
  • On the other hand, ActorId is a FIMService construct in the Activity so that rights check and a few other things happens appropriately (FIMService service account is pretty much omnipotent in an Activity)
  • Nothing prevents you to impersonate within your custom Activity (if you know what you are doing). For example, you can impersonate to make call outside of FIMService to do something else.