Azure应用服务中的Swagger身份验证

nsc4cvqm  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(171)

在我的Azure移动的.NET后端中,我想使用Azure Mobile .NET Server Swagger。我正在寻找一种快速的方法来隐藏swagger UI,使其不被公共访问?有没有办法只为选定的用户提供访问权限?

fcg9iug3

fcg9iug31#

先声明一句:即使你保护你的Swagger UI不被公众使用,你也没有保护你的API不被公众使用。你必须假设每个人都知道你的所有路由,并且有适当的安全措施来保护任何可能进入的请求。
Swashbuckle(将Swagger添加到Web API的部分)将一个自定义HttpMessageHandler添加到/swagger/ui路由(如此处所示)。如果您查看Web API pipeline,您可以看到,如果指定一个自定义处理程序,则可以绕过所有Controller选择、Auth过滤器等。这就是此处所发生的情况。
一些解决方案:
1.使用应用程序设置仅在调试模式下有条件地调用ConfigureSwagger(config)。这将阻止所有/swagger路由将其投入生产。或者,您可以使用暂存槽并仅在那里添加它。
1.你可以用Basic Auth MessageHandler这样的代码来 Package SwaggerUiHandler。如果用户选择/swagger/ui路径,这将提示用户输入基本的creds。请看下面我对这段代码的修改版本。
也许再多考虑一下,我们就能想出一个更好的解决方案--我在Swashbuckle repo中看到了几个问题(herehere),这表明您不是第一个遇到这个问题的人。

已修改的基本身份验证处理程序(来自here):

  • 警告:最低限度测试(并确保更改验证用户/通过的方式)*
public class BasicAuthMessageHandler : DelegatingHandler
{
    private const string BasicAuthResponseHeader = "WWW-Authenticate";
    private const string BasicAuthResponseHeaderValue = "Basic";

    public BasicAuthMessageHandler(HttpMessageHandler innerHandler)
    {
        this.InnerHandler = innerHandler;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        AuthenticationHeaderValue authValue = request.Headers.Authorization;
        HttpResponseMessage unauthorizedResponse = request.CreateUnauthorizedResponse();

        if (authValue != null && !string.IsNullOrWhiteSpace(authValue.Parameter))
        {
            Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
            if (parsedCredentials != null)
            {
                // TODO: Check that the user/pass are valid
                if (parsedCredentials.Username == "user" &&
                    parsedCredentials.Password == "pass")
                {
                    // If match, pass along to the inner handler
                    return base.SendAsync(request, cancellationToken);
                }
            }
        }
        else
        {
            // Prompt for creds
            unauthorizedResponse.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
        }

        return Task.FromResult(unauthorizedResponse);
    }

    private Credentials ParseAuthorizationHeader(string authHeader)
    {
        string[] credentials = Encoding.ASCII.GetString(Convert
                                                        .FromBase64String(authHeader))
                                                        .Split(
                                                        new[] { ':' });
        if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0])
            || string.IsNullOrEmpty(credentials[1])) return null;
        return new Credentials()
        {
            Username = credentials[0],
            Password = credentials[1],
        };
    }
}

正在注册Swagger路由

// Do this after calling ConfigureSwagger
ConfigureSwagger(config);

// Remove the swagger_ui route and re-add it with the wrapped handler.
var route = config.Routes["swagger_ui"];
config.Routes.Remove("swagger_ui");
config.Routes.MapHttpRoute("swagger_ui", route.RouteTemplate, route.Defaults, route.Constraints, new BasicAuthMessageHandler(route.Handler));

相关问题