【问题标题】:Swagger authentication in Azure App ServiceAzure 应用服务中的 Swagger 身份验证
【发布时间】:2016-03-08 20:05:32
【问题描述】:

在我的 Azure Mobile .NET 后端中,我想使用 Azure Mobile .NET Server Swagger 。我正在寻找从公共访问中隐藏招摇 UI 的快速方法?有没有办法只为选定的用户提供访问权限?

【问题讨论】:

    标签: azure azure-mobile-services swagger swagger-ui


    【解决方案1】:

    首先声明:即使您保护 Swagger UI 不被公开使用,也不能保护您的 API 不被公开使用。您必须假设每个人都知道您的所有路线,并且有适当的安全措施来保护可能进来的任何请求。

    话虽如此,但仍然没有一种简单的方法可以做到这一点。 Swashbuckle(将 Swagger 添加到 Web API 的部分)将自定义 HttpMessageHandler 添加到 /swagger/ui 路由(如 here 所示)。如果你查看Web API pipeline,你可以看到如果你指定一个自定义处理程序,你可以绕过所有的Controller选择、Auth过滤器等。这就是这里发生的事情。

    一些解决方案:

    1. 仅在调试模式下使用应用设置有条件地调用ConfigureSwagger(config)。这将阻止所有/swagger 路由将其投入生产。或者您可以使用暂存槽并仅将其添加到那里。
    2. 你可以用类似Basic Auth MessageHandler 的东西包裹SwaggerUiHandler。如果他们去/swagger/ui 路线,这将提示用户提供基本信用。请参阅下面的代码修改版本。

    也许我们可以想出一个更好的解决方案——我在 Swashbuckle 存储库中看到几个问题(herehere)表明你不是第一个遇到这个问题的人.

    修改后的 BasicAuthHandler(来自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));
    

    【讨论】:

    • 如果我尝试通过 config.Routes.Remove("swagger_ui") 删除 swagger_ui 路由,我收到以下错误: System.Web.Http 中发生“System.NotSupportedException”类型的异常.WebHost.dll 但未在用户代码中处理附加信息:“HostedHttpRouteCollection”不支持此操作。知道如何修改路线吗?
    • 您是否使用 GlobalConfiguration.Configure 来设置 Web API? asp.net/web-api/overview/advanced/…。我们所有的示例都使用 OWIN 自托管(文档与上一个链接在同一页面中),看起来如果您通过 GlobalConfiguration 运行,您会得到一个不支持 Remove 的不同 RouteCollection 类型。如果这就是你正在做的,我可以再调查一下。
    • 是的,我们正在使用 GlobalConfiguration,但我通过替换您的 config.Routes.Remove("swagger_ui"); 来修复它与 RouteTable.Routes.Remove(RouteTable.Routes["swagger_ui"]);现在它可以工作了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2020-06-10
    • 2016-07-26
    相关资源
    最近更新 更多