【问题标题】:ASP.NET Core 2.0: Authenticate a route without a controllerASP.NET Core 2.0:在没有控制器的情况下验证路由
【发布时间】:2018-03-28 06:55:16
【问题描述】:
我在this tutorial 之后将 Swagger 和 Swashbuckle 生成器添加到我的网站。现在,当导航到https://localhost:port/swagger/ 时,我可以看到生成的 API 文档。请注意,我没有创建任何 SwaggerController 类 - 这一切都由 NuGet 包处理。
问题是,我的整个站点,甚至是 API,都使用自定义 LDAP 进行了身份验证。我也想保护/swagger/ 页面。但是,我没有找到如何做到这一点的方法。 StackOverflow 上唯一相关的问题描述了adding authentication INTO swagger requests - 不验证整个 API 文档页面。
是否有特定的方法来保护生成的/swagger/ 页面?或者,是否有向 ASP.NET Core 2.0 MVC 路由添加身份验证验证器的通用方法?
【问题讨论】:
标签:
c#
authentication
routing
asp.net-core-mvc
swagger
【解决方案1】:
创建一个自定义中间件处理程序,然后将其添加到管道中,如下所示:
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseStaticFiles();
//And here's where the middleware is registered
app.UseRequestAuthHandler();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
中间件类:
namespace SwaggerDemo.Handlers
{
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
public class RequestAuthHandler
{
private const string _swaggerPathIdentifier = "swagger";
private readonly RequestDelegate _next;
public RequestAuthHandler(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
// First check if the current path is the swagger path
if (context.Request.Path.HasValue && context.Request.Path.Value.ToLower().Contains(_swaggerPathIdentifier))
{
// Secondly check if the current user is authenticated
if (!context.User.Identity.IsAuthenticated)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return;
}
}
await _next.Invoke(context);
}
}
public static class RequestAuthHandlerExtension
{
public static IApplicationBuilder UseRequestAuthHandler(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestAuthHandler>();
}
}
}
【解决方案2】:
我想出了以下解决方案:(灵感来自 Ryan 的解决方案)
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using System;
/// <summary>
/// The extension methods that extends <see cref="IApplicationBuilder" /> for authentication purposes
/// </summary>
public static class ApplicationBuilderExtensions
{
/// <summary>
/// Requires authentication for paths that starts with <paramref name="pathPrefix" />
/// </summary>
/// <param name="app">The application builder</param>
/// <param name="pathPrefix">The path prefix</param>
/// <returns>The application builder</returns>
public static IApplicationBuilder RequireAuthenticationOn(this IApplicationBuilder app, string pathPrefix)
{
return app.Use((context, next) =>
{
// First check if the current path is the swagger path
if (context.Request.Path.HasValue && context.Request.Path.Value.StartsWith(pathPrefix, StringComparison.InvariantCultureIgnoreCase))
{
// Secondly check if the current user is authenticated
if (!context.User.Identity.IsAuthenticated)
{
return context.ChallengeAsync();
}
}
return next();
});
}
}
如果您正确设置了身份验证机制,这会将用户重定向到登录页面。
然后,在构建您的应用程序时(例如为 NSwag)
app.RequireAuthenticationOn("/swagger");
//Enable Swagger + Swagger Ui
app.UseSwaggerUi3WithApiExplorer(this.ConfigureSwagger);