Как установить AuthorizationLevel для условия среды при запуске функции csproj в Azure Function Apps Runtime 2.x в контейнере Docker? - PullRequest
0 голосов
/ 05 сентября 2018

Я создаю приложение Azure Function v2.x (.NET Core 2, .csproj) и создаю образ докера (Ubuntu). При локальном запуске образа докера я хотел бы как-то дифференцировать свою среду, чтобы разрешить анонимный доступ во время работы внутри среды выполнения Azure 2.x внутри контейнера.

ОБНОВЛЕНИЕ № 2: Я не потерпел неудачу при запуске функции в контейнере Docker с использованием среды выполнения функций Azure - я не одинок. Поэтому я обратился к User Voice , чтобы предложить выставить переменную окружения, чтобы переопределить функциональную клавишу для локальных или других пользовательских ситуаций хостинга.

В более долгосрочной перспективе, возможно, Key Vault можно использовать для настройки ключа доступа и ссылки на него независимо от того, где работает функция. Все зависит от того, какие функции Azure используются в качестве платформы микросервисов, но очевидно, что история AuthN довольно неполна для среды выполнения.

ОБНОВЛЕНИЕ # 1: Как отмечает Камил , интерфейс командной строки Azure Functions неявно является «локальным», поэтому независимо от разрешения обходится. Это объясняет поведение отладки в VS 2017, но я все еще пытаюсь сформулировать стратегию обработки auth в библиотеках Azure Functions 2.x класса C, работающих в Docker. По сути, как я могу повлиять на конфигурацию HttpTrigger во время выполнения? Другие варианты функций Azure могут изменять привязку в файле function.json при развертывании.

У меня есть образец на GitHub для иллюстрации, но я продолжу объяснять и здесь.

Оригинальный вопрос: При локальной отладке в Visual Studio 2017 я предполагаю, что он изменяет файл functions.json на лету, чтобы сделать все безымянным. Так что даже когда у меня есть такая функция:

        public static async Task<HttpResponseMessage> Function(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
        TraceWriter log)

VS2017 позволит мне позвонить Почтальону без излишеств. Однако после запуска в Azure он будет ожидать либо параметр строки запроса, либо HTTP-заголовок [x-functions-key] для авторизации запроса.

Implicitly anonymous access (Джои не использовал ключ)

Однако, когда я собираю образ докера из папки вывода сборки, а затем запускаю этот же код в контейнере ...

docker build -t azfunc-sample <path_to_output_folder>

docker run -p 2077:80 azfunc-sample

Я получаю HTTP 401 обратно из контейнера на AuthorizeLevel.Function, но, конечно, AuthorizeLevel.Anonymous все еще в порядке.

No anonymous access

Это имеет смысл, учитывая, что среда выполнения функций Azure в Docker не знает, работает ли она локально или на какой-либо виртуальной машине Linux, но каким-то образом мне нужен способ заставить его делать то, что делает VS 2017. Я полагаю, что скомпилированные функции Azure сгенерировали function.json, и я не вижу очевидного способа параметризации HTTP-привязки с помощью переменной среды.

1 Ответ

0 голосов
/ 05 сентября 2018

Вы частично правы - фактически, то, почему локально, даже если функция защищена с помощью клавиши Function или Admin, вы можете получить к ней доступ как к Anonymous, так это то, что она использует Azure Functions CLI вместо реального времени выполнения. В CLI нет разницы между защищенными и незащищенными функциями, что вы можете увидеть в следующем коде:

private void DisplayHttpFunctionsInfo(WebScriptHostManager hostManager, Uri baseUri)
{
    if (hostManager != null)
    {
        var httpFunctions = hostManager.Instance.Functions.Where(f => f.Metadata.IsHttpFunction());
        if (httpFunctions.Any())
        {
            ColoredConsole
                .WriteLine()
                .WriteLine(Yellow("Http Functions:"))
                .WriteLine();
        }

        foreach (var function in httpFunctions)
        {
            var httpRoute = function.Metadata.Bindings.FirstOrDefault(b => b.Type == "httpTrigger").Raw["route"]?.ToString();
            httpRoute = httpRoute ?? function.Name;
            var extensions = hostManager.Instance.ScriptConfig.HostConfig.GetService<IExtensionRegistry>();
            var httpConfig = extensions.GetExtensions<IExtensionConfigProvider>().OfType<HttpExtensionConfiguration>().Single();
            var hostRoutePrefix = httpConfig.RoutePrefix ?? "api/";
            hostRoutePrefix = string.IsNullOrEmpty(hostRoutePrefix) || hostRoutePrefix.EndsWith("/")
                ? hostRoutePrefix
                : $"{hostRoutePrefix}/";
            var url = $"{baseUri.ToString()}{hostRoutePrefix}{httpRoute}";
            ColoredConsole
                .WriteLine($"\t{Yellow($"{function.Name}:")} {Green(url)}")
                .WriteLine();
        }
    }

Он просто использует маршруты без прикрепленных ключей. При запуске функции в контейнере также присоединяется среда выполнения, поэтому она работает как размещенная в облаке.

...