Problem:
After impersonating a user, clicking "Back to my account" in the user dropdown navigates to /Account/BackToImpersonator and fails with
:
Analysis:
ABP's AccountBlazorUserMenuContributor adds the Account.BackToImpersonator menu item with a GET URL and attaches ImpersonationComponent (a JS-submitted POST <form>) via UseComponent(). The LeptonX theme renders that attached component, so the POST works — OpenIddictImpersonateInferEndpointType hands form-POST requests to BackToImpersonatorModel.OnPostAsync (cookie re-sign-in).
But the Basic theme renders user-menu items as plain GET <a href> links and ignores the attached component. So the click issues a GET to /Account/BackToImpersonator, which the embedded OpenIddict server treats as an authorization request requiring a client_id → ID2029.
Question:
Is there a supported/built-in option to make "Back to my account" menu item work under the Basic theme so it submits as POST to /Account/BackToImpersonator?
3 Answer(s)
-
0
There is no built-in switch/option in the Basic theme that changes the user-menu rendering so that the built-in “Back to my account” item (which is designed to work via an attached component that submits a POST form) is automatically honored. In the Basic theme, the user menu is rendered as plain links, so a click becomes a GET to
/Account/BackToImpersonator, which can trigger the OpenIddictID2029behavior you observed.The supported way to make this work in Basic theme is to override how that menu item is rendered (i.e., render a component / custom markup that submits a POST form) using ABP’s “menu item component” customization.
- Concretely: remove/replace the default
Account.BackToImpersonatoritem in your menu contributor and re-add it as a customApplicationMenuItem(...).UseComponent(...)that renders a small<form method="post" action="/Account/BackToImpersonator">...</form>and submits it on click (the same idea LeptonX uses via the attachedImpersonationComponent). - This keeps the server-side ABP/OpenIddict impersonation endpoints untouched and fixes the theme rendering mismatch.
- Concretely: remove/replace the default
If you don’t want a custom component, the only other reliable approach is to override the Basic theme’s user-menu component/template so it actually renders
menuItem.Component(if provided) instead of always emitting<a href="...">.
(Validated) https://abp.io/docs/latest/framework/ui/blazor/basic-theme
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Need more assistance. It did not work
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
You're right, this is a Basic theme bug — its
LoginDisplayrenders every user-menu item as a plain<a href>and ignores the component attached viaUseComponent(...), so theImpersonationComponent(POST form) never gets rendered and the click hits OpenIddict as a GET → ID2029.Until the fix ships, you can replace the toolbar item with your own. Add
MyLoginDisplay.razorto your Blazor project:@using Blazorise @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Routing @using Microsoft.Extensions.Localization @using global::Localization.Resources.AbpUi @using Volo.Abp.MultiTenancy @using Volo.Abp.UI.Navigation @using Volo.Abp.Users @implements IDisposable @inject IMenuManager MenuManager @inject ICurrentUser CurrentUser @inject ICurrentTenant CurrentTenant @inject IStringLocalizer<AbpUiResource> L @inject NavigationManager Navigation <AuthorizeView> <Authorized> <Dropdown EndAligned="true"> <DropdownToggle Color="Color.Default"> @if (CurrentTenant.Name != null) { <span><i>@CurrentTenant.Name</i>\@CurrentUser.UserName</span> } else { <span>@CurrentUser.UserName</span> } </DropdownToggle> <DropdownMenu> @if (Menu != null) { @foreach (var menuItem in Menu.Items) { var componentType = menuItem.GetComponentTypeOrDefault(); if (componentType != null) { <DynamicComponent Type="@componentType" /> } else { <a class="dropdown-item" href="@menuItem.Url?.TrimStart('/', '~')" target="@menuItem.Target">@menuItem.DisplayName</a> } } } </DropdownMenu> </Dropdown> </Authorized> <NotAuthorized> <a class="nav-link" href="Account/Login">@L["Login"]</a> </NotAuthorized> </AuthorizeView> @code { private ApplicationMenu? Menu; protected override async Task OnInitializedAsync() { Menu = await MenuManager.GetAsync(StandardMenus.User); Navigation.LocationChanged += OnLocationChanged; } private void OnLocationChanged(object? sender, LocationChangedEventArgs e) => InvokeAsync(StateHasChanged); public void Dispose() => Navigation.LocationChanged -= OnLocationChanged; }Then a contributor to swap it in:
using System.Threading.Tasks; using Volo.Abp.AspNetCore.Components.Server.BasicTheme.Themes.Basic; using Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars; public class CustomLoginDisplayContributor : IToolbarContributor { public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) { if (context.Toolbar.Name == StandardToolbars.Main) { context.Toolbar.Items.RemoveAll(x => x.ComponentType == typeof(LoginDisplay)); context.Toolbar.Items.Add(new ToolbarItem(typeof(MyLoginDisplay))); } return Task.CompletedTask; } }Register it in your Blazor module's
ConfigureServices:Configure<Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars.AbpToolbarOptions>(options => { options.Contributors.Add(new CustomLoginDisplayContributor()); });We'll fix Basic theme itself in v10.4.2 so the workaround isn't needed.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)