- ABP Framework version: v6.0
- UI type: Angular
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): MVC
- Exception message and stack trace:
- Steps to reproduce the issue:"
Usign OpenIdDict
I try to utilize the impersonate({ tenantId, userId }) function in ImpersonationService through Angular in Abp Commercial, but whenever I use it I get the following stack trace in my log:
The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was marked as rejected by OpenIddict.Validation.OpenIddictValidationHandlers+ValidateToken.
The impersonateTenant and impersonateUser in ImpersonationService are both working, but I need to be able to impersonate a tenant user from the host.
4 Answer(s)
-
0
So the function impersonate in ImpersonationService that have tenantid and userid as parameters - this does not work?
I knew how to do this in Identity Server - but have no reference for Openiddict - do have no code for now! Just trying to use the impersonate function. And I can see that the call is made and that the payload is correct when looking at ImpersonateUser or ImpersonateTenant. But the server code somehow does not work correctly.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
1
I have now solved this by doing an override of the existing functionality. Providing code here for others reference:
- Create ExtendedImpersonationExtensionGrant.cs in HttpApi.Host
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using System; using System.Security.Claims; using System.Threading.Tasks; using Volo.Abp.Account.Web.ExtensionGrants; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Identity; using Volo.Abp.MultiTenancy; using Volo.Abp.OpenIddict.ExtensionGrantTypes; namespace xxx.xxxxxx { public class ExtendedImpersonationExtensionGrant : ImpersonationExtensionGrant { protected IDataFilter _dataFilter { get; set; } public override Task<IActionResult> HandleAsync(ExtensionGrantContext context) { _dataFilter = ServiceProviderServiceExtensions.GetRequiredService<IDataFilter>(context.HttpContext.RequestServices); return base.HandleAsync(context); } protected async override Task<IActionResult> ImpersonateUserAsync(ExtensionGrantContext context, ClaimsPrincipal principal, Guid? tenantId, Guid userId) { if (!tenantId.HasValue && !this.currentTenant.IsAvailable) { IdentityUser foundUser = null; using (_dataFilter.Disable<IMultiTenant>()) { // host user foundUser = await this.userManager.FindByIdAsync(userId.ToString()); } if (foundUser != null) // impersonate directly into user in tenant! { return await base.ImpersonateUserAsync(context, principal, foundUser.TenantId, foundUser.Id); } } return await base.ImpersonateUserAsync(context, principal, tenantId, userId); } protected async override Task<IActionResult> BackToImpersonatorAsync(ExtensionGrantContext context, ClaimsPrincipal principal, Guid? tenantId, Guid userId) { IdentityUser foundUser = null; using (_dataFilter.Disable<IMultiTenant>()) { // host user foundUser = await this.userManager.FindByIdAsync(userId.ToString()); } if (foundUser != null && !foundUser.TenantId.HasValue) // Possible to revert back to host user { return await base.BackToImpersonatorAsync(context, principal, foundUser.TenantId, foundUser.Id); } return await base.BackToImpersonatorAsync(context, principal, tenantId, userId); } } }- in HttpApi.HostModule.cs under ConfigureServices(ServiceConfigurationContext context) function add the following:
this.Configure<AbpOpenIddictExtensionGrantsOptions>((Action<AbpOpenIddictExtensionGrantsOptions>)(options => { options.Grants.Remove("Impersonation"); options.Grants.Add("Impersonation", (IExtensionGrant)new ExtendedImpersonationExtensionGrant()); }));Then it works calling the following in Angular - and you can log in to a user under a tenent directly from a host and back again using standard functions:
this.impersonationService.impersonateUser(entity.id).subscribe((result) => { this.toaster.success('::Logged in - please wait'); })Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)