aspnetcore: Endpoint routing can not invoke a static file middleware

Describe the bug

The static file middleware does not allow any form of serving of files when used in combination with endpoint routing. Maybe I am missing something here, but this prevents me from doing stuff like this:

Notice I am essentially trying to add auth to my Swagger UI without writing a custom middleware.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();

    var swaggerUiDelegate = endpoints.CreateApplicationBuilder().UseSwaggerUI(options =>
    {
        // Set documentation route to /docs
        options.RoutePrefix = "docs";
    })
    .Build();

    endpoints.Map("docs/{*wildcard}", swaggerUiDelegate).RequireAuthorization("Swagger");
});

To Reproduce

The above code should work if you essentially just add Swashbuckle to your project and attempt to add auth to your Swagger UI.

Exceptions (if any)

InvalidOperationException: The request reached the end of the pipeline without executing the endpoint: ‘docs/{*wildcard}’. Please register the EndpointMiddleware using ‘IApplicationBuilder.UseEndpoints(…)’ if using routing.

Further technical details

  • ASP.NET Core version = 3.1
  • Include the output of dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.1.201
 Commit:    b1768b4ae7

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.15
 OS Platform: Darwin
 RID:         osx.10.15-x64
 Base Path:   /usr/local/share/dotnet/sdk/3.1.201/

Host (useful for support):
  Version: 5.0.0-preview.7.20364.11
  Commit:  53976d38b1

.NET SDKs installed:
  2.1.805 [/usr/local/share/dotnet/sdk]
  3.1.201 [/usr/local/share/dotnet/sdk]
  3.1.302 [/usr/local/share/dotnet/sdk]
  5.0.100-preview.7.20366.6 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.17 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.17 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0-preview.7.20365.19 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.17 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.20 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.6 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0-preview.7.20364.11 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download
  • The IDE (VS / VS Code/ VS4Mac) you’re running on, and it’s version Visual Studio 2019 for Mac

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 1
  • Comments: 17 (10 by maintainers)

Most upvoted comments

It should work but I think you can simplify it. You don’t need a custom middleware, or to restore the endpoint value after the middleware.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();

    var swaggerUiDelegate = endpoints.CreateApplicationBuilder()
    .Use((context, next) =>
    {
        context.SetEndpoint(null);
        return next();
    })
    .UseSwaggerUI(options =>
    {
        // Set documentation route to /docs
        options.RoutePrefix = "docs";
    })
    .Build();

    endpoints.Map("docs/{*wildcard}", swaggerUiDelegate).RequireAuthorization("Swagger");
});

A completely different way of doing this is setting the FallbackPolicy so that all requests require authentication. https://docs.microsoft.com/en-us/aspnet/core/security/authorization/secure-data?view=aspnetcore-3.1#require-authenticated-users

The workaround @Tratcher posted works but this seems like something to be provided out-of-the-box.

Any update here? although I think the swagger package should provide such APIs, e.g. endpoints.MapSwaggerUI()

there is a question as to whether the request should flow back into the parent middleware pipeline if it reaches the end without an endpoint being executed…

Routing endpoints are considered terminal, there’s no concept right now of an optional handler. Even if the request did re-enter the main pipeline, the endpoint executing middleware is itself terminal and placed at the end of the pipeline, there’d be nowhere to go but 404.