dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.45k stars 10.03k forks source link

Enhanced nav: support redirections triggered by non-Blazor code #53606

Open SteveSandersonMS opened 9 months ago

SteveSandersonMS commented 9 months ago

Currently, during an enhanced nav POST request, redirections to external URLs will only work if they are triggered by NavigationManager.NavigateTo(url). They do not work if triggered through any other API, such as httpContext.Response.Redirect. This is a problem because other ASP.NET middleware may issue redirections, for example to auth endpoints.

Customer impact

Blazor enhanced forms are often used to perform data access, such as saving changes via a POST, or simpler gestures like "add to cart" in eShop. But it's always possible that your authentication token has expired and that some non-Blazor middleware is going to intercept the request and perform a redirection to an external URL for reauthentication.

Right now there's no sensible way to manage this other than simply not enabling enhancement on the form. Unless you can 100% guarantee that no other middleware might issue a redirection, you just can't use Enhance or data-enhance, because any such redirection will lead to an error.

We could make redirections work regardless of what code triggered them.

Proposed solution

Blazor should, in some way, hook into the ASP.NET Core request processing pipeline (via middleware or any other mechanism) so that it can detect the case of "enhanced nav request leads to a redirection" and perform the same response translation that Blazor's renderer does for NavigationException.

The logic would look the same as we have in EndpointHtmlRenderer.Prerendering.cs: https://github.com/dotnet/aspnetcore/blob/5d0e3b0513a1fd71aa4a63029b91d57504b59345/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Prerendering.cs#L203-L213

The perf impact would be negligible since it starts by checking for method=post and the presence of the enhanced nav marker header, and if either is absent it's a no-op.

Note

We considered doing this in .NET 8 but decided not to take the risk of affecting non-Blazor endpoints so close to the final release. For .NET 9 we have more opportunity to attempt it.

javiercn commented 9 months ago

The challenging bit here is to do this in a "transparent" way I think. I hope we don't end up with a middleware in the pipeline to deal with this, but the only alternatives I can think of is hooking up into OnResponseStarting)) to change the response accordingly.

Otherwise, things like the auth Challenge or code that sets the status code on the response won't work.

Maybe we can figure out a way in which we can wire up middleware conditionally to the default builder, I think that would be good enough.

At that point we would check for POST+enhanced nav header and attach a delegate to the context to apply the enhanced nav protocol if we see a redirect triggered.

I think that will be good enough as it won't be in the user's code by default and can be wired up explicitly if needed be.

javiercn commented 9 months ago

For how to wire up middleare implicitly check src/DefaultBuilder/src/WebApplicationBuilder.cs

ghost commented 9 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.