Open Closed

Menu not rendering after user logs in - Blazor wasm #5830


User avatar
0
olitrepanier created
  • ABP Framework version: v7.3.2
  • UI Type: Blazor WASM
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: no exception
  • Steps to reproduce the issue:

Hello,

We have a very weird problem. Once the user logs in, the menu is not fully rendering and clicking on the user's avatar does nothing. The rendering only works after we the refresh the page.

We found out that every authorize call, except for the first Login one, returns an error with payload:

Here's what the query string parameters look like for the authorize request:

What's even more curious is that, when we refresh the page, we do get the authorize call, which returns us an error, but like mentionned earlier, the UI works!

Here are the requests when I first login: The first authorize after the Login is successful, the others aren't

I even find currentUser: { isAuthenticated: true... } when fetching from application-configuration

We can't reproduce the problem locally.

We use Authorization Code Flow, which seems to be working. I can find an access and id token in Chrome's session storage (although I can't find a refresh token for some reason?).

The application is deployed to Azure. We use two app services. One for the Blazor wasm and the other for the API. Both app services have websockets enabled.

I have found a similar case that was reported on this forum a couple months back #4503, but no final solution is documented.


23 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    What's your abp version? Are you using the latest lepton package?

    Can you share an online URL? Include a test user. Thanks

    liming.ma@volosoft.com

  • User Avatar
    0
    olitrepanier created

    I believe we're at 2.3.3 for Lepton and 7.3.3 for abp

    I sent you an email with the url and test user.

    Thanks

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can troubleshoot by creating a new template project and deploying it to the production environment to see if the problem exists.

    If the problem doesn't exist,please compare the code or share your project with me.

    Thanks

  • User Avatar
    0
    olitrepanier created

    Hello

    We created a new template project with: abp new VanillaAbp -t app-pro -u blazor

    and deployed it here: https://kog-vanilla-blazor.azurewebsites.net/ https://kog-vanilla-api.azurewebsites.net/

    And we seem to be getting the exact same errors.

    Were using a self-signed X509 certificate to sign the tokens. Were running the exact same command in the Docker file to generate it.

  • User Avatar
    0
    olitrepanier created

    I tried to deploy with all the available themes: Basic, Lepton and LeptonX. I am still getting the problem with all of them. I even tried the newest version of abp 7.3.3

    We generated a certificate with the following command: dotnet dev-certs https -v -ep authserver.pfx -p patate123

    and we added the authserver.pfx in the root folder of the HttpApi.Host project like so:

    In order for the authserver.pfx to be included when building the csproj, we added these lines to the HttpApi.Host.csproj:

    And in the code where the .pfx is consumed, we had to change these lines in order for the app to fetch the certificate properly:

    The way we configured the certificate doesn't seems to be the problem since I can login and get an access token, but could it cause an issue when the app tries to authorize the user?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    and deployed it here: https://kog-vanilla-blazor.azurewebsites.net/ https://kog-vanilla-api.azurewebsites.net/

    hi

    Thanks. I will check the code.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I checked the code and everything works as expected. Can you publish this project to iis or another environment?

  • User Avatar
    0
    olitrepanier created

    Hello again

    I tried to deploy to Azure Web App Linux Containers both the api and the blazor app.

    I generated the docker images by using the script build-images-locally.ps1, pushed the generated images to an Azure Container Registry and then successfully deployed the images to Azure Web App Linux containers.

    You can find the applications at the following urls: https://kog-docker-blazor.azurewebsites.net/ https://kog-docker-api.azurewebsites.net/

    The problem that I am having right now is that azure containers forward https requests to http (this is normal). I was having issues when trying to log in because IdentityServer is expecting https.

    Therefore, I disabled RequireHttpsMetadata in the appsettings.json file like so:

    But that becomes a problem after I login because the blazor app requests the token at an http endpoint:

    Looking at the openid-configuration returned, I see that all the endpoints returned are http and not https:

    I tried following this post to fix the issue, without any success.

    I need my openid-configuration to return https endpoints.

    Heres the error I get in the console:

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Can you try this?

    if (!env.IsDevelopment())
    {
        app.Use((context, next) =>
        {
            context.Request.Scheme = "https";
            return next();
        });
    }
    
  • User Avatar
    0
    olitrepanier created

    Hello,

    I tried the code you provided and it fixes my problem with the configuration returning http instead of https

    So I have no issue login in, but I still have the same problem with the login-callback returning "user is not logged" in error and the UI not working until I refresh the page.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    I can reproduce the problem, I will check it.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Could you share the full app logs? thanks

  • User Avatar
    0
    olitrepanier created

    Hello,

    Let me know if this url works for you:

    https://pastebin.com/A0mKCw9W

    I pasted the logs there.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Will it work if you try this(in the Blazor project)?

    [ExposeServices(typeof(MainMenuProvider))]
    public class MyMainMenuProvider : MainMenuProvider
    {
        private readonly IMenuManager _menuManager;
        public MyMainMenuProvider(IMenuManager menuManager,
            IObjectMapper<AbpAspNetCoreComponentsWebLeptonXThemeModule> objectMapper) : base(menuManager, objectMapper)
        {
            _menuManager = menuManager;
        }
    
        public override async Task<MenuViewModel> GetMenuAsync()
        {
            var menu = await _menuManager.GetMainMenuAsync();
    
            //Menu = _objectMapper.Map<ApplicationMenu, MenuViewModel>(menu);
            var result = new MenuViewModel
            {
                Menu = menu,
                Items = menu.Items.Select(CreateMenuItemViewModel).ToList()
            };
            result.SetParents();
    
            return result;
        }
        
        private MenuItemViewModel CreateMenuItemViewModel(ApplicationMenuItem applicationMenuItem)
        {
            var viewModel = new MenuItemViewModel
            {
                MenuItem = applicationMenuItem,
                Items = new List<MenuItemViewModel>()
            };
    
            foreach (var item in applicationMenuItem.Items)
            {
                viewModel.Items.Add(CreateMenuItemViewModel(item));
            }
    
            return viewModel;
        }
    }
    
  • User Avatar
    0
    olitrepanier created

    Hello again,

    With that code, it looks like the menu loads properly and works on the first login.

    I am still having issues with the admin profile icon that does not work when I click on it. It only works after refreshing the page.

    Also, I am still receiving responses in the Network tab of chrome that says "user is not logged in"

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Also, I am still receiving responses in the Network tab of chrome that says "user is not logged in"

    This is the design of Blazor, you can ignore it.

    I am still having issues with the admin profile icon that does not work when I click on it. It only works after refreshing the page.

    I will check it.

    BTW, your ticket was refunded..

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can try this. please let me know if it works.

    Add patch.js to the wwwroot folder(in the Blazor project)

    window.resetLeptonXToolbar = function () {
        leptonx.init.initializers[5]();
    }
    

    Add script to index.html

    Override component

    [ExposeServices(typeof(MainHeaderToolbarUserMenu))]
    public class MyMainHeaderToolbarUserMenu : MainHeaderToolbarUserMenu
    {
        protected async override Task OnInitializedAsync()
        {
            await SetUserMenuAndProfileAsync();
    
            Navigation.LocationChanged += OnLocationChanged;
            ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged;
        }
        
        private async void ApplicationConfigurationChanged()
        {
            await SetUserMenuAndProfileAsync();
            await InvokeAsync(StateHasChanged);
        }
    
        private async Task SetUserMenuAndProfileAsync()
        {
            UserMenu = await MenuManager.GetAsync(StandardMenus.User);
    
            UserId = CurrentUser.Id;
            UserName = CurrentUser.UserName;
            UserFullName = CalculateUserFullName();
            UserEmail = CurrentUser.Email;
            TenantName = CurrentTenant.Name;
    
            if (UserId != null)
            {
                ProfileImageUrl = RemoteServiceOptions.Value.RemoteServices.GetConfigurationOrDefaultOrNull("AbpAccountPublic")?.BaseUrl.EnsureEndsWith('/') +
                                  $"api/account/profile-picture-file/{UserId}";
            }
            
            await JsRuntime.InvokeVoidAsync("resetLeptonXToolbar");
        }
        
        public new void Dispose()
        {
            Navigation.LocationChanged -= OnLocationChanged;
            ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged;
        }
    }
    
  • User Avatar
    0
    olitrepanier created

    Hello again,

    It does work. I have to override the correct menu. There is a SideMenu and a TopMenu. The one that works for me is the SideMenu.

    I am still getting the login-callback errors in the console that says "user is not logged in". Any clue why this is happening?

  • User Avatar
    0
    olitrepanier created

    Oh I didnt see your message that says that its Blazor's design. Do you have any documentation I could read that explains it?

    Also, could you also explain to me what was happening in the default components I need to override? In case another problem of the sort happens.

    Thank you for the refund, I appreciate it.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Oh I didnt see your message that says that its Blazor's design. Do you have any documentation I could read that explains it?

    The Microsoft document does not explain in detail, it just briefly mentions it.

    AuthenticationService handles the low-level details of the OIDC protocol. The app internally calls methods defined in the script to perform the authentication operations.

    https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-authentication-library?view=aspnetcore-7.0&tabs=visual-studio#index-page

    Check the source code and you will find that it will try to process the callback every time the application starts. https://github.com/dotnet/aspnetcore/blob/release/7.0/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/AuthenticationService.ts#L520

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Also, could you also explain to me what was happening in the default components I need to override? In case another problem of the sort happens.

    Because the component is rendered in real-time, it did not bind the initialization event. call events after rendering components through this temporary solution.

    We will fix it in the next patch version, you can safely delete them in a later version(Leptonx Theme package)

  • User Avatar
    0
    olitrepanier created

    Hello again,

    Thanks for the information.

    We also have the issue with the toolbar user menu in mobile mode. Any idea which code I need to override to make this component work?

    After that, everything should be fine.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can try this:

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(MobileNavbar))]
    public class MyMobileWasmNavbar : MobileWasmNavbar, IDisposable
    {
    	public const string LogoutMenuName = "UserMenu.SideMenu.Logout";
    	protected override string LoginLink => "/authentication/login";
    	
    	[Inject] 
    	IOptions<AbpRemoteServiceOptions> AbpRemoteServiceOptions { get; set; }
    	
    	[Inject]
    	protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; }
    	
    	[Inject]
    	protected IJSRuntime JsRuntime { get; set; }
    
    	protected override async Task OnInitializedAsync()
    	{
    		await SetMenuAndProfileAsync();
    		ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged;
    	}
    	
    	private async void ApplicationConfigurationChanged()
            {
            await SetMenuAndProfileAsync();
            await InvokeAsync(StateHasChanged);
            }
    	
    	private async Task SetMenuAndProfileAsync()
    	{
    		UserMenu = await MenuManager.GetAsync(StandardMenus.User);
    
    		var menu = await MainMenuProvider.GetMenuAsync();
    
    		SelectedMenuItems = Options.Value.MobileMenuSelector(menu.Items.AsReadOnly()).Take(2).ToList();
    
    		if (CurrentUser.IsAuthenticated && CurrentUser.Id != null)
    		{
    			ProfileImageUrl = GetProfilePictureURL(CurrentUser.GetId());
    		}
    
    		if (CurrentUser.IsAuthenticated)
    		{
    			UserMenu.AddItem(new UI.Navigation.ApplicationMenuItem(
    				LogoutMenuName,
    				L["Logout"],
    				"/authentication/logout",
    				icon: "bi bi-power"));
    		}
            
    		await JsRuntime.InvokeVoidAsync("resetLeptonXToolbar");
    	}
    
    	protected override string GetProfilePictureURL(Guid userId)
    	{
    		return AbpRemoteServiceOptions.Value.RemoteServices
    			       .GetConfigurationOrDefaultOrNull("AbpAccountPublic")?
    			       .BaseUrl.EnsureEndsWith('/')
    		       + $"api/account/profile-picture-file/{userId}";
    	}
    
    	public void Dispose()
    	{
    		ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged;
    	}
    }
    
Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11