Aspnetcore.docs: And Blazor pages?

Created on 30 Mar 2020  ·  8Comments  ·  Source: dotnet/AspNetCore.Docs

A lot of confusing statements on Microsoft Docs, Stackoverflow, etc. Basically, it works in Blazor until you use a non-local browser (e.g. mobile). Guidance is clear to use AuthenticationStateProvider for A&A activity in Blazor. But what about the other uses of HttpContext? UrlHelperFactory needs an ActionContext, which needs an HttpContext. And RouteData, which needs RouteValues, which come from HttpContext. A lot of non A&A uses for HttpContext not accessible to Blazor. (LinkGenerator is often suggested, but docs are truly woeful there.)


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Blazor P3 Source - Docs.ms doc-enhancement

All 8 comments

@guardrex Should this issue be in the Blazor docs?

@Rick-Anderson can you please add a section to the referenced doc article clarifying that the HttpContext is not applicable to Blazor apps. @anurse should this also include a statement about SignalR?

I'm not totally sure what we'd want to put here. There _is_ a mechanism to get an HttpContext in SignalR, but we generally recommend against using it unless absolutely necessary (since it has weird behavior, particularly when using Long Polling).

@BrennanConroy @davidfowl @halter73 for thoughts.

Sounds to me that is exactly what you want to tell people:
A) There is a mechanism to get HttpContext in SignalR.
B) It can produce unexpected behavior, particularly using Long Polling
C) It should not be used unless absolutely necessary. Otherwise it is strongly recommended not to.
D) Use at your own risk.
⚠️ 💀 ☢️ 💥 🔥

Where is the HttpContext being retrieved from? IHttpContextAccessor?

From the linked doc:

It's only necessary to use IHttpContextAccessor when you need access to the HttpContext inside a service.

I don't think this guidance goes far enough. We should have blanket guidance against using IHttpContextAccessor unless there really are no other options. It's far better to have services that absolutely require an HttpContext to get it passed in by middleware via a method argument.

IHttpContextAccessor encourages usage of the HttpContext outside of the middleware pipeline. This is very dangerous because HttpContext is not thread safe. If something is using the HttpContext that isn't awaited by middleware, there's likely a thread safety issue.

Sometimes, when there's indirection before the service is called (even though it's ultimately called and awaited by middleware), a method argument isn't an option. Logging providers that want to enhance logs with request metadata are an example of this. In that case, using IHttpContextAccessor might be acceptable. But even with that, there have been issues in the past.

Out of curiosity, what exactly is wrong with the HttpContext in blazor? I know SignalR does some weird HttpContext cloning for long polling, but what breaks exactly? It would be interesting to know if it's something we could make work vs. an unsupportable scenario.

btw @mkArtakMSFT on ...

clarifying that the HttpContext is not applicable to Blazor apps

Here are the cases where it comes up tangentially (i.e., server-side) ...

The built-in AuthenticationStateProvider service obtains authentication state data from ASP.NET Core's HttpContext.User.

... at ... https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.1#authenticationstateprovider-service

The TokenProvider class uses HttpContext when passing tokens to a Blazor Server app ...

@{
    var tokens = new InitialApplicationState
    {
        AccessToken = await HttpContext.GetTokenAsync("access_token"),
        RefreshToken = await HttpContext.GetTokenAsync("refresh_token")
    };
}

... at ... https://docs.microsoft.com/en-us/aspnet/core/security/blazor/server?view=aspnetcore-3.1&tabs=visual-studio#pass-tokens-to-a-blazor-server-app

Support for hosted Blazor prerendering with auth makes use of HttpContext ...

<app>
    @if (!HttpContext.Request.Path.StartsWithSegments("/authentication"))
    {
        <component type="typeof(Wasm.Authentication.Client.App)" render-mode="Static" />
    }
    else
    {
        <text>Loading...</text>
    }
</app>

... at ... https://docs.microsoft.com/en-us/aspnet/core/security/blazor/webassembly/?view=aspnetcore-3.1#support-prerendering-with-authentication

For Blazor Server, there's a bit on setting the current culture in a cookie that can be read by the Localization Middleware so that the culture ultimately can be used by components ...

public class HostModel : PageModel
{
    public void OnGet()
    {
        HttpContext.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }
}

... at ... https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-3.1#cookies

@mkArtakMSFT Closing this now given the work on prior PRs. I think it's well covered at this point.

@bdnts See the coverage at ...

... which is repeated at ...

https://docs.microsoft.com/aspnet/core/security/blazor/server/threat-mitigation#blazor-and-shared-state

... and passing tokens to the app works in Blazor Server scenarios ...

https://docs.microsoft.com/aspnet/core/security/blazor/server/additional-scenarios#pass-tokens-to-a-blazor-server-app

Was this page helpful?
0 / 5 - 0 ratings