Swashbuckle 中的 Swagger API 和 UI 是实施的 https://github.com/domaindrivendev/Swashbuckle/blob/master/Swashbuckle.Core/Application/HttpConfigurationExtensions.cs#L91 as HttpMessageHandler
为路线。因此过滤器在那里不起作用(因为它们仅适用于 ASP.NET WebAPI 的控制器和操作)。
但是,您可以以不同的方式防止未经授权的访问 swagger。如果您使用 ASP.NET Web API 作为 Owin 中间件(通过使用微软.AspNet.WebApi.Owin https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Owin/5.2.7nuget 包),那么你可以编写简单的中间件并将其放在 swagger 中间件之前,以拒绝对“swagger/docs/”和“swagger/ui/”(Swagger API 和 UI 的默认路由)的请求。
例如:
[assembly: OwinStartupAttribute(typeof(WebApplicationMvcWebApiSwagger.Startup))]
namespace WebApplicationMvcWebApiSwagger
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.UseRejectUnathorizedUsersForSwagger();
var config = new HttpConfiguration();
config
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "A title for your API");
})
.EnableSwaggerUi();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
}
}
public static class SwaggerAuthorizationMiddleware
{
public static void UseRejectUnathorizedUsersForSwagger(this IAppBuilder appBuilder)
{
appBuilder.Use((context, next) =>
{
if (context.Request.Path.Value.StartsWith("/swagger/docs/")
|| context.Request.Path.Value.StartsWith("/swagger/ui/"))
{
var user = (context.Request.User as ClaimsPrincipal);
if (user == null || !user.Identity.IsAuthenticated)
{
context.Response.StatusCode = 401;
context.Response.ContentType = "text/plain";
return context.Response.WriteAsync("Unauthorized. Log in to use swagger.");
}
}
return next.Invoke();
});
}
}
}
ConfigureAuth(app)
是一个负责身份验证的中间件(此处由使用 ASP.NET Identity 的 Visual Studio 模板生成)。在 auth 中间件之后和 WebApi 中间件之前(这也增加了 swagger),您可以将自己的中间件与自定义身份验证逻辑一起放置。
如果您不使用 Owin for ASP.NET API 那么您可以尝试实现HttpMessageHandler
并添加与之前的 OWIN 中间件示例类似的逻辑。你应该能够使用Thread.CurrentPrincipal https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api#authentication获取授权数据(或HttpContext.Current.User https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api#setting-the-principal在 IIS 中托管时?对此我不确定):
protected void Application_Start()
{
//...
GlobalConfiguration.Configure(WebApiConfig.Register);
//...
}
config.MessageHandlers.Add(new RequireAdminUserForSwaggerDocAndUiHandler());
config
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "A title for your API");
})
.EnableSwaggerUi();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
public class RequireAdminUserForSwaggerDocAndUiHandler : DelegatingHandler
{
async protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.RequestUri.PathAndQuery.StartsWith("/swagger/docs/")
|| request.RequestUri.PathAndQuery.StartsWith("/swagger/ui/"))
{
if (Thread.CurrentPrincipal == null || !Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
var response = new HttpResponseMessage();
response.StatusCode = System.Net.HttpStatusCode.Unauthorized;
response.Content = new StringContent("Unauthorized. Log in to use swagger.");
return response;
}
}
return await base.SendAsync(request, cancellationToken);
}
}