You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current guidance for working with a Web API with SSR/Pre-rendering enabled is to create a server-side and a client-side service implementation.
I view this guidance as problematic from a security standpoint, as it leads to two different authorization stacks being used for the same essential data/operation, which can e.g. cause unintentional data leakage due to forgetting to update either the razor or the web api with the appropriate security requirements.
Thus you now have two different authorization stacks in place for the same fundamental data/action.
In this particular case the authorization requirements are the same
However, one can quite easily imagine a scenario where the specs say that the data from IWeatherForecaster should be restricted by MyPolicy, and the dev only adds it to the endpoint registration (or vice versa, only adds it to the razor componet), leading to an authorization hole where depending on whether the page is rendered entirely CSR or SSR/pre-rendered you have different policies applied, leading to unintended information disclosure. This is particularly problematic as it can easily escape immediate user-testing as you would have to ensure that you actually access the page both as pure CSR rendering and as SSR/pre-rendered
This problem only gets worse as an application becomes more complex. In the particular case illustrated by the sample, there is a one-to-one correspondence between data exposed by the /weather-forecast endpoint and the Weather.razor page. Such a one-to-one correlation between an api and a razor component is not going to always exist, leading to even more opportunity for unintended information disclosure when different data has different authorization requirements
A potential solution would be to consolidate authorization logic into the ServerWeatherForecaster.cs, but that would appear to negate any declarative usage of the ASP.NET Core authorization stack altogether and could cause other problems (e.g., how would you force [Authorize("mypolicy")] attributes to be checked if they decorated the ServerWeatherForecaster or IWeatherForecaster? How would that authorization flow through to http 401 or 403 responses for unauthorized users calling the web api?)
With today's framework, I believe you could omit the service abstractions and just call the Web API directly during pre-rendering by configuring an HttpClient in the Server project to pass-through the incoming user identity when calling the web api.
This should resolve concerns about ambiguity during authorization, since authorization for the service becomes the sole responsibility of the web api
This section applies to Blazor Web Apps that maintain a web API in the server project or transform web API calls to an external web API.
...
The server version can typically access the server-side resources directly. Injecting an HttpClient on the server that makes calls back to the server isn't recommended, as the network request is typically unnecessary.
This guidance appears to be primarily performance related, so could a mechanism be introduced to optimize HttpClient calls to the same application during pre-rendering?
Provide a means to "unify" the authorization stacks between SSR/Pre-rendering and web api.
So for example, you could decorate your Service interface with with any of the authorization attributes supported by ASP.NET Core in a single place, and both blazor-pre-rendering and web api would honor them from that single interface
The goal is to have a single, unified authorization stack that applies no matter how the service is called (whether via web api, or SSR/pre-rendering), that is compatible with the current ASP.NET Core web api authorization stack.
Provide a more streamlined mechanism to show e.g. a "loading" template for SSR/pre-rendering that resolves to the normal web api once CSR comes online
In one sense, this is "less ambitious", since it seeks to only pre-render the general page structure instead of pre-rendering the whole page with all data already retrieved
if you want to change this you either inject a service to detect prerendering or use the OnAfterRenderAsync hook instead of the OnInitlializedAsync Hook. Or disable prerendering.
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
Text = await _webScraper.Get();
StateHasChanged();
}
}
However:
this approach does not make an appearance on the documentation page "Call a web API from ASP.NET Core Blazor", and I'm unsure if it has other downsides (my understanding how how Blazor rendering state works still has a lot of holes)
If you don't get the condition around calling StateHasChanged() correct, you can end up getting an infinite loop of calls to your web api
StateHasChanged() seems perhaps too coarse-grained? Thinking here about a component that calls multiple web apis, and perhaps references other components with their own api calls (Again, lots of holes in my current understanding of Blazor rendering state).
Additional context
No response
The text was updated successfully, but these errors were encountered:
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
This originally started with the docs issue #34586 - IMovieService example can lead to authorization problems
Possibly related:
The current guidance for working with a Web API with SSR/Pre-rendering enabled is to create a server-side and a client-side service implementation.
I view this guidance as problematic from a security standpoint, as it leads to two different authorization stacks being used for the same essential data/operation, which can e.g. cause unintentional data leakage due to forgetting to update either the razor or the web api with the appropriate security requirements.
Copying from the Docs issue:
cc: @guardrex dotnet/AspNetCore.Docs#34586
Describe the solution you'd like
A few broad options come to mind:
Provide a mechanism to "inline" HttpClient calls
Provide a means to "unify" the authorization stacks between SSR/Pre-rendering and web api.
Provide a more streamlined mechanism to show e.g. a "loading" template for SSR/pre-rendering that resolves to the normal web api once CSR comes online
StateHasChanged()
correct, you can end up getting an infinite loop of calls to your web apiStateHasChanged()
seems perhaps too coarse-grained? Thinking here about a component that calls multiple web apis, and perhaps references other components with their own api calls (Again, lots of holes in my current understanding of Blazor rendering state).Additional context
No response
The text was updated successfully, but these errors were encountered: