Sometimes code must be invoked with admin-user priviledge, e.g. when retrieving data to which invoking user has no access.
In this scenario You can impersonate OrganizationService to other user only for time operation is executing.
Invoking code which must be run with higher priviledged is extremely easy. Code is written just like it is in SharePoint.
CRMSecurity.RunWithElevatedPrivileges(_accountPrototype.OrganizationService, () => { _accountProjects = _accountPrototype.GetRelatedProjects(); });
public static class CRMSecurity { #region Delegate /// <summary> /// Delegate code to run with elevated privileges. /// </summary> [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Must be public in roder to invoke from anywhere.")] public delegate void CodeToRunElevated(); #endregion #region Public Methods /// <summary> /// Runs the code with elevated privileges. /// </summary> /// <param name="organizationService">The organization service.</param> /// <param name="codeDelegate">The code delegate.</param> public static void RunWithElevatedPrivileges(IOrganizationService organizationService, CodeToRunElevated codeDelegate) { using (new OrganizationSecurityWrapper(organizationService, "DOMAIN_NAME_HERE")) { var secureCode = codeDelegate; secureCode(); } } /// <summary> /// Runs the code with elevated privileges. /// </summary> /// <param name="organizationService">The organization service.</param> /// <param name="userDomainName">Name of the user domain.</param> /// <param name="codeDelegate">The code delegate.</param> public static void RunWithElevatedPrivileges(IOrganizationService organizationService, string userDomainName, CodeToRunElevated codeDelegate) { using (new OrganizationSecurityWrapper(organizationService, userDomainName)) { var secureCode = codeDelegate; secureCode(); } } #endregion }
public class OrganizationSecurityWrapper : IDisposable { #region Fields private readonly Guid _callerId; private readonly OrganizationServiceProxy _service; #endregion #region Constructors public OrganizationSecurityWrapper(IOrganizationService service, string domainName) { if (service == null) throw new ArgumentNullException("service"); _service = (OrganizationServiceProxy)service; var systemUser = SystemUserHelper.GetSystemUser(_service, domainName); if (systemUser == null) throw new CannotFindSystemUserException(domainName); _callerId = _service.CallerId; _service.CallerId = systemUser.Id; } #endregion #region IDisposable /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="disposing"><c>True</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (_service != null) _service.CallerId = _callerId; } #endregion }
Hope it helps 🙂