
Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
History is littered with hundreds of conflicts over the future of a community, group, location or business that were "resolved" when one of the parties stepped ahead and destroyed what was there. With the original point of contention destroyed, the debates would fall to the wayside. Archive Team believes that by duplicated condemned data, the conversation and debate can continue, as well as the richness and insight gained by keeping the materials. Our projects have ranged in size from a single volunteer downloading the data to a small-but-critical site, to over 100 volunteers stepping forward to acquire terabytes of user-created data to save for future generations.
The main site for Archive Team is at archiveteam.org and contains up to the date information on various projects, manifestos, plans and walkthroughs.
This collection contains the output of many Archive Team projects, both ongoing and completed. Thanks to the generous providing of disk space by the Internet Archive, multi-terabyte datasets can be made available, as well as in use by the Wayback Machine, providing a path back to lost websites and work.
Our collection has grown to the point of having sub-collections for the type of data we acquire. If you are seeking to browse the contents of these collections, the Wayback Machine is the best first stop. Otherwise, you are free to dig into the stacks to see what you may find.
The Archive Team Panic Downloads are full pulldowns of currently extant websites, meant to serve as emergency backups for needed sites that are in danger of closing, or which will be missed dearly if suddenly lost due to hard drive crashes or server failures.
Is there an existing issue for this?
Describe the bug
EF Core, if two independent execution contexts invoke any method, notices and throws an exception like 'A second operation started on this context before a previous asynchronous operation completed.'. This has been covered in a number of Blazor related issues: #17004, #16745, etc. Because of the way Blazor server-side works, with a single scope for the duration of the circuit, and multiple Components being able to enter InitializeAsync (etc) at the same time, EF Core's standard scoped model DbContext cannot work.
The recommended solution is to use either OwnedComponentBase, or resolve your DbContext's differently.
Okay. Fine.
A problem I haven't seen mentioned is how this causes issues when adding a Blazor-server application into an existing ASP.Net Core API service, while using Authorization Policies.
It is pretty normal practice, in a ASP.NET Core API, to implement custom AuthorizationRequirement and AuthorizationRequirementHandler classes, to check that certain users have access to certain policies, or resources. It is also fairly normal practice to make use of EF Core from within these Handler classes. Existing sites do this. Custom Handler classes, that evaluate the success or failure of the policy based on queries to a database.
Under normal circumstances, this works fine. AuthorizationRequirementHandler instances are scoped. And thus created for the Request. And called by DefaultAuthorizationService within the request, once.
However, simply adding a Blazor server-side application to the Web project can easily break this. Blazor has components such as AuthorizeRouteView and AuthorizeView, that as part of their component logic, resolve the AuthorizationService, and attempt to authorize the user. When running in server-side Blazor, these invocations happen during the Render (or potentially prerender) phase. And since Blazor has a habit of allowing components, each in the same Scope, to independently internal logic (InitializeAsync, etc, can be called for multiple components at the same time), it is quite easy for two independent async calls to enter into the same AuthorizationService instance at the same time. Thus, traversing down into the custom AuthorizationRequirementHandler instances, and thus down into EF Core.
This issue cannot be solved with OwnedComponentBase, since AuthorizeView and AuthorizeRouteView are the potential components that will cause this issue, and these cannot be overridden to inherit from a new base class.
This leaves one remaining option I can see: to edit your AuthorizationRequirementHandler to create nested container scopes, simply to use EF Core. This can solve the problem.
However, AuthorizationRequirementHandlers are shared between Blazor server-side and traditional MVC and Controller code. This has the unfortunate effect of forcing you to edit your AuthorizationRequirementHandler code to create nested scopes, for Blazor, but have those nested scopes created even during MVC or API Controller requests. And, worse, since it's pretty difficult to determine whether you are inside a Blazor render call or not, you can't conditionally do this within the Handlers.
Essentially, you have to write your AuthorizationRequirementHandlers in a special way, for both MVC and API controllers, simply in order to add a Blazor server-side application into the project. Blazor ends up forcing your to pollute code that otherwise wouldn't need it.
There might be other ASP.Net internal classes that are subject to this same issue. But, as it's very typical to use EF Core within AuthorizationRequirementHandlers, this is the only one I noticed.
Expected Behavior
I would expect Blazor to not introduce additional unexpected coding requirements against existing classes that conform to the basic requirements of ASP.Net Core. If Blazor intends to request AuthorizationService, and make use of it, it should expect that traditionally that class was registered scoped, and may need to take special care in the case of reentrant async executions.
Steps To Reproduce
Extend AuthorizationRequirementHandler. Conduct a EF Core operation within AuthorizeAsync. Register with ASP.Net Core. See that it works.
Add a Blazor server side application to the same project. Add an AuthorizeView. See that Blazor begins failing in the EF Core calls.
Exceptions (if any)
No response
.NET Version
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: