-
-
Save hikalkan/8862d9f7ae8b4874976d to your computer and use it in GitHub Desktop.
| /* SAMPLE AJAX CALL to this action: | |
| (This is enough since it's automatically redirected to the target tenant's ImpersonateSignIn action) | |
| abp.ajax({ | |
| url: abp.appPath + 'Account/Impersonate', | |
| data: JSON.stringify({ | |
| tenantId: 1, //Target tenant id (can be null if target user is a host user) | |
| userId: 2 //Target user id | |
| }) | |
| }); | |
| */ | |
| [AbpMvcAuthorize(AppPermissions.Pages_Administration_Users_Impersonation)] | |
| public virtual async Task<JsonResult> Impersonate(ImpersonateModel model) | |
| { | |
| CheckModelState(); | |
| if (AbpSession.ImpersonatorUserId.HasValue) | |
| { | |
| throw new UserFriendlyException(L("CascadeImpersonationErrorMessage")); | |
| } | |
| if (AbpSession.TenantId.HasValue) | |
| { | |
| if (!model.TenantId.HasValue) | |
| { | |
| throw new UserFriendlyException(L("FromTenantToHostImpersonationErrorMessage")); | |
| } | |
| if (model.TenantId.Value != AbpSession.TenantId.Value) | |
| { | |
| throw new UserFriendlyException(L("DifferentTenantImpersonationErrorMessage")); | |
| } | |
| } | |
| return await SaveImpersonationTokenAndGetTargetUrl(model.TenantId, model.UserId, false); | |
| } | |
| [UnitOfWork] | |
| public virtual async Task<ActionResult> ImpersonateSignIn(string tokenId) | |
| { | |
| var cacheItem = await _cacheManager.GetImpersonationCache().GetOrDefaultAsync(tokenId); | |
| if (cacheItem == null) | |
| { | |
| throw new UserFriendlyException(L("ImpersonationTokenErrorMessage")); | |
| } | |
| //Switch to requested tenant | |
| using (_unitOfWorkManager.Current.SetFilterParameter(AbpDataFilters.MayHaveTenant, AbpDataFilters.Parameters.TenantId, cacheItem.TargetTenantId)) | |
| { | |
| //Get the user from tenant | |
| var user = await _userManager.FindByIdAsync(cacheItem.TargetUserId); | |
| //Create identity | |
| var identity = await _userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); | |
| if (!cacheItem.IsBackToImpersonator) | |
| { | |
| //Add claims for audit logging | |
| if (cacheItem.ImpersonatorTenantId.HasValue) | |
| { | |
| identity.AddClaim(new Claim(AbpClaimTypes.ImpersonatorTenantId, cacheItem.ImpersonatorTenantId.Value.ToString(CultureInfo.InvariantCulture))); | |
| } | |
| identity.AddClaim(new Claim(AbpClaimTypes.ImpersonatorUserId, cacheItem.ImpersonatorUserId.ToString(CultureInfo.InvariantCulture))); | |
| } | |
| //Sign in with the target user | |
| AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); | |
| AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = false }, identity); | |
| //Remove the cache item to prevent re-use | |
| await _cacheManager.GetImpersonationCache().RemoveAsync(tokenId); | |
| return RedirectToAction("Index", "Application"); | |
| } | |
| } | |
| /* SAMPLE AJAX CALL to this action: | |
| (This is enough since it's automatically redirected to the host's ImpersonateSignIn action) | |
| abp.ajax({ | |
| url: abp.appPath + 'Account/BackToImpersonator' | |
| }); | |
| */ | |
| public virtual async Task<JsonResult> BackToImpersonator() | |
| { | |
| if (!AbpSession.ImpersonatorUserId.HasValue) | |
| { | |
| throw new UserFriendlyException(L("NotImpersonatedLoginErrorMessage")); | |
| } | |
| return await SaveImpersonationTokenAndGetTargetUrl(AbpSession.ImpersonatorTenantId, AbpSession.ImpersonatorUserId.Value, true); | |
| } | |
| private async Task<JsonResult> SaveImpersonationTokenAndGetTargetUrl(int? tenantId, long userId, bool isBackToImpersonator) | |
| { | |
| //Create a cache item | |
| var cacheItem = new ImpersonationCacheItem( | |
| tenantId, | |
| userId, | |
| isBackToImpersonator | |
| ); | |
| if (!isBackToImpersonator) | |
| { | |
| cacheItem.ImpersonatorTenantId = AbpSession.TenantId; | |
| cacheItem.ImpersonatorUserId = AbpSession.GetUserId(); | |
| } | |
| //Create a random token and save to the cache | |
| var tokenId = Guid.NewGuid().ToString(); | |
| await _cacheManager | |
| .GetImpersonationCache() | |
| .SetAsync(tokenId, cacheItem, TimeSpan.FromMinutes(1)); | |
| //Find tenancy name | |
| string tenancyName = null; | |
| if (tenantId.HasValue) | |
| { | |
| tenancyName = (await _tenantManager.GetByIdAsync(tenantId.Value)).TenancyName; | |
| } | |
| //Create target URL | |
| var targetUrl = _webUrlService.GetSiteRootAddress(tenancyName) + "Account/ImpersonateSignIn?tokenId=" + tokenId; | |
| return Json(new MvcAjaxResponse { TargetUrl = targetUrl }); | |
| } | |
| #endregion |
| [Serializable] | |
| public class ImpersonationCacheItem | |
| { | |
| public const string CacheName = "AppImpersonationCache"; | |
| public int? ImpersonatorTenantId { get; set; } | |
| public long ImpersonatorUserId { get; set; } | |
| public int? TargetTenantId { get; set; } | |
| public long TargetUserId { get; set; } | |
| public bool IsBackToImpersonator { get; set; } | |
| public ImpersonationCacheItem() | |
| { | |
| } | |
| public ImpersonationCacheItem(int? targetTenantId, long targetUserId, bool isBackToImpersonator) | |
| { | |
| TargetTenantId = targetTenantId; | |
| TargetUserId = targetUserId; | |
| IsBackToImpersonator = isBackToImpersonator; | |
| } | |
| } |
| public static class ImpersonationCacheManagerExtensions | |
| { | |
| public static ITypedCache<string, ImpersonationCacheItem> GetImpersonationCache(this ICacheManager cacheManager) | |
| { | |
| return cacheManager.GetCache<string, ImpersonationCacheItem>(ImpersonationCacheItem.CacheName); | |
| } | |
| } |
Hi,
I was trying to implement user impersonation. Couldn't find the ImpersonateModel class. Please could you suggest how to get it. Am I missing any reference?
Please do u know how I can impersonate from a background job?
If you are asking for AspNet Boilerplate, see https://aspnetboilerplate.com/Pages/Documents/Abp-Session#overriding-current-session-values
public class MyService
{
private readonly IAbpSession _session;
public MyService(IAbpSession session)
{
_session = session;
}
public void Test()
{
using (_session.Use(42, null))
{
var tenantId = _session.TenantId; //42
var userId = _session.UserId; //null
}
}
}Hi, I have two different test site on Azure. When I click "Login as this user" or "Login as this tenant" on second site (for example testsite2.azurewebsites.net), Impersonate method returns the first sites url (testsite1.azurewebsites.net/Account/ImpersonateSignIn?tokenId=" + tokenId) and I get error like "Impersonation token is invalid or expired". This only happens on second site. First site is working as expected. I did not change anything on Account/Impersonate method.
This is the code we use in ASP.NET ZERO (http://aspnetzero.com) for user impersonation.