-
-
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.