使用用户名和密码保护 swagger 文档页面 Asp Net Core 2.1

Jos*_*igh 12 asp.net swagger swashbuckle asp.net-core-webapi

我正在使用带有 Swashbuckle.aspnetcore.swagger 的 Asp.Net Core 2.1 Web Api

我想在授予访问权限之前使用用户名和密码保护 api 文档页面。

示例文档页面 在此处输入图片说明

确保公众无法访问

Sha*_*ica 12

Github 上的 mguinness 的回答中复制:


在 .NET Core 中,您使用中间件,而不是 DelegatingHandler:

public class SwaggerAuthorizedMiddleware
{
    private readonly RequestDelegate _next;

    public SwaggerAuthorizedMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/swagger")
            && !context.User.Identity.IsAuthenticated)
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return;
        }

        await _next.Invoke(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

您还需要一个扩展方法来帮助添加到管道:

public static class SwaggerAuthorizeExtensions
{
    public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<SwaggerAuthorizedMiddleware>();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在使用 Swagger 之前添加到 Startup.cs 中的 Configure 方法:

app.UseSwaggerAuthorized();
app.UseSwagger();
app.UseSwaggerUi();
Run Code Online (Sandbox Code Playgroud)

还有一个变体解决方案发布在那里如何使用 basic auth 做到这一点


Gau*_*rma 12

我在 git 中找到了解决方案并应用于我的项目。它按预期工作。

下面的代码是从那里复制的。

public class SwaggerBasicAuthMiddleware
{

private readonly RequestDelegate next;

    public SwaggerBasicAuthMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        //Make sure we are hitting the swagger path, and not doing it locally as it just gets annoying :-)
        if (context.Request.Path.StartsWithSegments("/swagger") && !this.IsLocalRequest(context))
        {
            string authHeader = context.Request.Headers["Authorization"];
            if (authHeader != null && authHeader.StartsWith("Basic "))
            {
                // Get the encoded username and password
                var encodedUsernamePassword = authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim();

                // Decode from Base64 to string
                var decodedUsernamePassword = Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword));

                // Split username and password
                var username = decodedUsernamePassword.Split(':', 2)[0];
                var password = decodedUsernamePassword.Split(':', 2)[1];

                // Check if login is correct
                if (IsAuthorized(username, password))
                {
                    await next.Invoke(context);
                    return;
                }
            }

            // Return authentication type (causes browser to show login dialog)
            context.Response.Headers["WWW-Authenticate"] = "Basic";

            // Return unauthorized
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        }
        else
        {
            await next.Invoke(context);
        }
    }

    public bool IsAuthorized(string username, string password)
    {
        // Check that username and password are correct
        return username.Equals("SpecialUser", StringComparison.InvariantCultureIgnoreCase)
                && password.Equals("SpecialPassword1");
    }

    public bool IsLocalRequest(HttpContext context)
    {
        //Handle running using the Microsoft.AspNetCore.TestHost and the site being run entirely locally in memory without an actual TCP/IP connection
        if (context.Connection.RemoteIpAddress == null && context.Connection.LocalIpAddress == null)
        {
            return true;
        }
        if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))
        {
            return true;
        }
        if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))
        {
            return true;
        }
        return false;
    }
}
public static class SwaggerAuthorizeExtensions
    {
        public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<SwaggerBasicAuthMiddleware>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

在 Startup.cs 中

app.UseAuthentication(); //Ensure this like is above the swagger stuff

app.UseSwaggerAuthorized();
app.UseSwagger();
app.UseSwaggerUI();
Run Code Online (Sandbox Code Playgroud)

  • 欢迎提供解决方案的链接,但请确保您的答案在没有它的情况下也有用:[在链接周围添加上下文](//meta.stackexchange.com/a/8259) 这样您的其他用户就会知道它是什么以及为什么它在那里,然后引用您链接到的页面中最相关的部分,以防目标页面不可用。[仅是链接的答案可能会被删除。](//stackoverflow.com/help/deleted-answers) (2认同)