在Azure App Service中进行全面认证 [英] Swagger authentication in Azure App Service

查看:55
本文介绍了在Azure App Service中进行全面认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Azure Mobile .NET后端中,我想使用

In my Azure Mobile .NET backend I want to use Azure Mobile .NET Server Swagger . I'm looking for fast way to hide swagger UI from public access ? Is there any way to provide access only for selected users ?

推荐答案

首先免责声明:即使您保护Swagger UI免受公共消费,也并未保护API不受公共消费.您必须假设每个人都知道您的所有路线,并且具有适当的安全性来保护可能出现的任何请求.

First a disclaimer: Even if you protect your Swagger UI from public consumption, you are not protecting your APIs from public consumption. You have to assume that everyone knows all of your routes and have the appropriate security in place to protect any requests that may come in.

话虽如此,仍然没有简单的方法可以做到这一点. Swashbuckle (向Web API添加Swagger的片段)向/swagger/ui路由添加了自定义HttpMessageHandler (如此处所示).如果您查看 Web API管道,则可以看到如果您指定了自定义处理程序,则可以绕过所有Controller选择,Auth过滤器等.这就是这里发生的情况.

That being said, there's still not a simple way to do this. Swashbuckle (the piece that adds Swagger to Web API) adds a custom HttpMessageHandler to the /swagger/ui route (as seen here). If you look at the Web API pipeline, you can see that if you specify a custom handler, you can bypass all of the Controller selection, Auth filters, etc. This is what happens here.

一些解决方案:

  1. 使用应用程序设置仅在调试模式下有条件地调用ConfigureSwagger(config).这将阻止所有/swagger路线投入生产.或者,您可以使用暂存插槽,然后仅在其中添加它.
  2. 您可以使用SwaggerUiHandler ="nofollow">基本身份验证MessageHandler .如果他们选择了/swagger/ui路线,这将提示用户提供基本的信誉.有关此代码的修改版本,请参见下文.
  1. Use an app setting to conditionally call ConfigureSwagger(config) in debug modes only. This would prevent all /swagger routes from making it into production. Or you could use a staging slot and only add it there.
  2. You can wrap the SwaggerUiHandler with something like this Basic Auth MessageHandler. This would prompt the user for basic creds if they went to the /swagger/ui route. See below for my modified version of this code.

也许还有一点想法,我们可以提出一个更好的解决方案-我看到了几个问题(此处此处)表示您已不是第一个碰到这个的人.

Maybe with a little more thought we can come up with a better solution -- I see a couple of issues (here and here) in the Swashbuckle repo that indicate you're not the first one to hit this.

修改后的BasicAuthHandler(来自这里):

Modified BasicAuthHandler (from 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));

这篇关于在Azure App Service中进行全面认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆