Back in the days, we could use the following code to set the current principal:

PrincipalInfo.CurrentPrincipal = PrincipalInfo.CreatePrincipal("my-username");

PrincipalInfo.CreatePrincipal was then marked as obsolete, and we were supposed to use IUserImpersonation instead:

[Obsolete("Use IUserImpersonation")]
public static IPrincipal CreatePrincipal(string username) => ServiceLocator.Current.GetInstance<IUserImpersonation>().CreatePrincipal(username);

However, in CMS 12, PrincipalInfo.CurrentPrincipal has become read-only.

To set the current principal in CMS 12, you can use the following code:

// constructor injection
private readonly IPrincipalAccessor _principalAccessor;
private readonly IUserImpersonation _userImpersonation;

...

_principalAccessor.Principal = await _userImpersonation.CreatePrincipalAsync("my-username");

Happy coding!