Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor Api call in OnInitializedAsync() with auth and UserMiddleware crash #52350

Closed
1 task done
fdonnet opened this issue Nov 24, 2023 · 2 comments
Closed
1 task done
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@fdonnet
Copy link

fdonnet commented Nov 24, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When I call an api from a blazor page I think my middleware crash and I don't understand why


<button class="btn btn-primary" @onclick="SayHello">SayHello</button>
<p role="status">Say: @say</p>

@code {
    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }
    private string say = string.Empty;

    private async Task SayHello()
    {
        var client = Factory.CreateClient("WebApp");
        say = await client.GetStringAsync("/Hello");
    }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var isAuthenticated = (await authenticationState).User.Identity?.IsAuthenticated;

            if (isAuthenticated == true)
            {
                var client = Factory.CreateClient("WebApp");
                var test = await client.GetStringAsync("/Hello");
            }
        }

    }
}

If the api call is called inside OnInitializedAsync it doesn't work, when it's trigger by the Hello button outside of OnInitializedAsync it works.

I wait the authenticatioState correctly I think.

It crash server side in my user middleware, when I set my user

   public class UserServiceMiddleware(RequestDelegate next)
    {
        private readonly RequestDelegate next = next ?? throw new ArgumentNullException(nameof(next));

        public async Task InvokeAsync(HttpContext context, UserService service)
        {
            service.SetUser(context.User);
            await next(context);
        }
    }

(like explained here https://learn.microsoft.com/en-us/aspnet/core/blazor/security/server/additional-scenarios?view=aspnetcore-8.0) to be able to inject my user in other services server side.

Very strange.

Expected Behavior

Same behavior as calling the API with a button click... I'dont understand why my middleware creates this issue for OnInitializedAsync. It crash on await next(context);

Steps To Reproduce

No response

Exceptions (if any)

it returns

HttpRequestException: Response status code does not indicate success: 302 (Found).

    System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
    System.Net.Http.HttpClient.GetStringAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
    Ubik.Accounting.WebApp.Client.Pages.Auth.OnInitializedAsync() in Auth.razor

                    var test = await client.GetStringAsync("/Hello");

Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.WaitForResultReady(bool waitForQuiescence, PrerenderedComponentHtmlContent result)
Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, bool waitForQuiescence)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext+<>c+<<InvokeAsync>b__10_0>d.MoveNext()
Ubik.Accounting.WebApp.Security.UserServiceMiddleware.InvokeAsync(HttpContext context, UserService service) in UserServiceMiddleware.cs

                await next(context);

Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

.NET Version

8.0

Anything else?

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Nov 24, 2023
@fdonnet
Copy link
Author

fdonnet commented Nov 24, 2023

This guy bcheung4589 helped me a lot with the explanation here #51468 to manage auto mode... that's why I had my issue and his facade proposition works for me... now that my page is called from server first and from wasm after, I only need to understand why my initial data load is cleaned after the first render

  • I see my object collection from a direct call server side and it disapear

@fdonnet fdonnet closed this as completed Nov 24, 2023
@bcheung4589
Copy link

bcheung4589 commented Nov 24, 2023

I have a direct answer for you, as Ive experienced this personally.

Problem: on the second run, UserServiceMiddleware isnt executed and so UserService stays empty => with all its further consequences.

Solution: what to do? Refactor UserService with RequireUserAsync(ClaimsPrincipal user).

Implementation: in the razor component (yes, Im also not 100% satisfied with this solution, but it works for now):

    protected override async Task OnInitializedAsync()
    {
        // Require User or move away.
        await UserService.RequireUserAsync(AuthenticationStateProvider, Navigation);

        // Run as usual.
        await base.OnInitializedAsync();
    }

@ghost ghost locked as resolved and limited conversation to collaborators Feb 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

2 participants