Триггер HTTP в Функциях Azure

Триггер HTTP позволяет вызвать функцию с помощью HTTP-запроса. Триггер HTTP можно использовать для создания независимых от сервера API-интерфейсов и для ответа веб-перехватчикам.

Возвращаемое по умолчанию значение для функции, активируемой по HTTP:

  • HTTP 204 No Content с пустым телом в Функциях 2.x и более поздних версий;
  • HTTP 200 OK с пустым телом в Функциях 1.x.

Чтобы изменить HTTP-ответ, настройте выходную привязку.

Дополнительные сведения о привязках HTTP см. в обзорной статье и справочнике по выходным привязкам.

Совет

Если вы планируете использовать привязки HTTP или веб-перехватчика, спланируйте работу так, чтобы избежать нехватки портов, которая может возникнуть в результате неправильной установки HttpClient. См. дополнительные сведения об управлении подключениями в службе "Функции Azure".

Внимание

В этой статье используются вкладки для поддержки нескольких версий модели программирования Node.js. Модель версии 4 общедоступна и предназначена для более гибкого и интуитивно понятного интерфейса для разработчиков JavaScript и TypeScript. Дополнительные сведения о том, как работает модель версии 4, см. в руководстве разработчика по Функции Azure Node.js. Дополнительные сведения о различиях между версиями 3 и 4 см. в руководстве по миграции.

Функции Azure поддерживает две модели программирования для Python. Способ определения привязок зависит от выбранной модели программирования.

Модель программирования Python версии 2 позволяет определять привязки с помощью декораторов непосредственно в коде функции Python. Дополнительные сведения см. в руководстве разработчика Python.

Эта статья поддерживает обе модели программирования.

Пример

Функцию C# можно создать с помощью одного из следующих режимов C#:

  • Изолированная рабочая модель: скомпилированная функция C#, которая выполняется в рабочем процессе, изолированном от среды выполнения. Изолированный рабочий процесс необходим для поддержки функций C#, работающих в LTS и не LTS-версиях .NET и платформа .NET Framework. Расширения для изолированных рабочих процессов используют Microsoft.Azure.Functions.Worker.Extensions.* пространства имен.
  • Модель внутрипроцессного процесса: скомпилированная функция C#, которая выполняется в том же процессе, что и среда выполнения Функций. В варианте этой модели функции можно запускать с помощью скриптов C#, которая поддерживается главным образом для редактирования портала C#. Расширения для функций в процессе используют Microsoft.Azure.WebJobs.Extensions.* пространства имен.

Весь код в этой статье по умолчанию использует синтаксис .NET Core, стандартный для Функций Azure версии 2.x и более поздних. Сведения о синтаксисе версии 1.x см. на странице с соответствующими шаблонами функций.

В следующем примере показан триггер HTTP, который возвращает ответ hello, world в качестве IActionResult, используя интеграцию ASP.NET Core в .NET Isolated:

[Function("HttpFunction")]
public IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
{
    return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
}

В следующем примере показан триггер HTTP, который возвращает ответ "hello world" в виде объекта HttpResponseData.

[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger(nameof(HttpFunction));
    logger.LogInformation("message logged");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("Welcome to .NET isolated worker !!");

    return response;
}

Этот раздел содержит следующие примеры.

Этот тип привязки HTTP представлен в следующих примерах.

Чтение параметра из строки запроса

Этот пример считывает параметр с именем id из строки запроса и использует его, чтобы создать документ JSON, возвращаемый клиенту, с типом содержимого application/json.

@FunctionName("TriggerStringGet")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("GET parameters are: " + request.getQueryParameters());

    // Get named parameter
    String id = request.getQueryParameters().getOrDefault("id", "");

    // Convert and display
    if (id.isEmpty()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String name = "fake_name";
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

Чтение текста из запроса POST

Этот пример считывает текст из запроса POST как String и использует его, чтобы создать документ JSON, возвращаемый клиенту, с типом содержимого application/json.

    @FunctionName("TriggerStringPost")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req", 
              methods = {HttpMethod.POST}, 
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Request body is: " + request.getBody().orElse(""));

        // Check request body
        if (!request.getBody().isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        } 
        else {
            // return JSON from to the client
            // Generate document
            final String body = request.getBody().get();
            final String jsonDocument = "{\"id\":\"123456\", " + 
                                         "\"description\": \"" + body + "\"}";
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(jsonDocument)
                          .build();
        }
    }

Чтение параметра из маршрута

Этот пример считывает обязательный параметр с именем id и необязательный параметр name из пути маршрута и использует их для создания документа JSON, возвращаемого клиенту, с типом содержимого application/json.

@FunctionName("TriggerStringRoute")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS,
            route = "trigger/{id}/{name=EMPTY}") // name is optional and defaults to EMPTY
        HttpRequestMessage<Optional<String>> request,
        @BindingName("id") String id,
        @BindingName("name") String name,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Route parameters are: " + id);

    // Convert and display
    if (id == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

Чтение текста POJO из запроса POST

Ниже приведен код для класса ToDoItem, указанного в этом примере:


public class ToDoItem {

  private String id;
  private String description;  

  public ToDoItem(String id, String description) {
    this.id = id;
    this.description = description;
  }

  public String getId() {
    return id;
  }

  public String getDescription() {
    return description;
  }

  @Override
  public String toString() {
    return "ToDoItem={id=" + id + ",description=" + description + "}";
  }
}

Этот пример считывает текст запроса POST. Текст запроса автоматически десериализуется в объект ToDoItem и возвращается к клиенту с типом содержимого application/json. Параметр ToDoItem сериализуется средой выполнения службы "Функции", так как он назначен свойству body класса HttpMessageResponse.Builder.

@FunctionName("TriggerPojoPost")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.POST}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<ToDoItem>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Request body is: " + request.getBody().orElse(null));

    // Check request body
    if (!request.getBody().isPresent()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final ToDoItem body = request.getBody().get();
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(body)
                        .build();
    }
}

В следующем примере показана функция Триггера HTTP TypeScript. В функции выполняется поиск параметра name в строке запроса или в тексте HTTP-запроса.

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || (await request.text()) || 'world';

    return { body: `Hello, ${name}!` };
}

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: httpTrigger1,
});

В следующем примере показана функция JavaScript триггера HTTP. В функции выполняется поиск параметра name в строке запроса или в тексте HTTP-запроса.

const { app } = require('@azure/functions');

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || (await request.text()) || 'world';

        return { body: `Hello, ${name}!` };
    },
});

В следующем примере показаны привязка триггера в файле function.json и функция PowerShell. В функции выполняется поиск параметра name в строке запроса или в тексте HTTP-запроса.

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

$body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body       = $body
})

В следующем примере показана привязка триггера и функция Python, использующая привязку. В функции выполняется поиск параметра name в строке запроса или в тексте HTTP-запроса. Пример зависит от того, используется ли модель программирования Python версии 1 или версии 2.

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
def test_function(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    return func.HttpResponse(
        "This HTTP triggered function executed successfully.",
        status_code=200
        )

Атрибуты

Библиотеки C# в процессе и изолированном рабочем процессе используются HttpTriggerAttribute для определения привязки триггера. Вместо этого скрипт C# использует файл конфигурации function.json, как описано в руководстве по скриптам C#.

В изолированных приложениях-функциях HttpTriggerAttribute рабочих процессов поддерживаются следующие параметры:

Параметры Description
AuthLevel Определяет, какие ключи (если они требуются) должны присутствовать в запросе, чтобы вызвать функцию. Поддерживаемые значения см. на уровне авторизации.
Методы Массив методов HTTP, на которые отвечает функция. Если свойство не указано, функция отвечает на все методы HTTP. См. раздел Настройка конечной точки HTTP.
Маршрут Шаблон маршрута, определяющий URL-адреса запросов, на которые отвечает функция. Если значение не указано, по умолчанию используется <functionname>. См. раздел Настройка конечной точки HTTP.

Декораторы

Применяется только к модели программирования Python версии 2.

Для функций Python версии 2, определенных с помощью декоратора, в декораторе определяются route следующие свойства триггера, добавляющие привязку HttpTrigger и HttpOutput:

Свойство Description
route Маршрут для конечной точки HTTP. Если значение None, оно будет присвоено имени функции, если оно присутствует или имя определяемой пользователем функции Python.
trigger_arg_name Имя аргумента для HttpRequest. Значение по умолчанию — req.
binding_arg_name Имя аргумента для HttpResponse. Значение по умолчанию — "$return".
methods Кортеж методов HTTP, к которым отвечает функция.
auth_level Определяет, какие ключи (если они требуются) должны присутствовать в запросе, чтобы вызвать функцию.

Сведения о функциях Python, определенных с помощью function.json, см. в разделе "Конфигурация ".

Заметки

В библиотеке среды выполнения функций Java используйте заметку HttpTrigger, которая поддерживает следующие параметры:

Настройка

Применяется только к модели программирования Python версии 1.

В следующей таблице описываются свойства, которые можно задать для options объекта, переданного методу app.http() .

Свойство Description
authLevel Определяет, какие ключи (если они требуются) должны присутствовать в запросе, чтобы вызвать функцию. Поддерживаемые значения см. на уровне авторизации.
methods Массив методов HTTP, на которые отвечает функция. Если свойство не указано, функция отвечает на все методы HTTP. См. раздел Настройка конечной точки HTTP.
маршрут Шаблон маршрута, определяющий URL-адреса запросов, на которые отвечает функция. Если значение не указано, по умолчанию используется <functionname>. См. раздел Настройка конечной точки HTTP.

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

В следующей таблице описываются свойства конфигурации привязки, которые задаются в файле function.json.

Свойство в function.json Описание
type Обязательное. Необходимо задать значение httpTrigger.
direction Обязательное. Необходимо задать значение in.
name Обязательное. Имя переменной, из которой в коде функции можно получить запрос или текст запроса.
authLevel Определяет, какие ключи (если они требуются) должны присутствовать в запросе, чтобы вызвать функцию. Поддерживаемые значения см. на уровне авторизации.
methods Массив методов HTTP, на которые отвечает функция. Если свойство не указано, функция отвечает на все методы HTTP. См. раздел Настройка конечной точки HTTP.
маршрут Шаблон маршрута, определяющий URL-адреса запросов, на которые отвечает функция. Если значение не указано, по умолчанию используется <functionname>. См. раздел Настройка конечной точки HTTP.

Использование

В этом разделе описано, как настроить привязку функции триггера HTTP.

Заметка HttpTrigger должна применяться к параметру метода одного из следующих типов.

  • HttpRequestMessage<T>.
  • Все собственные типы Java, такие как int, String, byte[].
  • Значения, которые могут принимать значение NULL, являются необязательными.
  • Любой обычный тип объекта Java (POJO).

Полезная нагрузка

Тип входных данных триггера объявлен как один из следующих типов:

Тип Описание
HttpRequest Использование этого типа требует, чтобы приложение было настроено с помощью интеграции ASP.NET Core в .NET Isolated.
Это обеспечивает полный доступ к объекту запроса и общему httpContext.
HttpRequestData Проекция объекта запроса.
Настраиваемый тип Если текст запроса — JSON, среда выполнения попытается проанализировать его, чтобы задать свойства объекта.

Если параметр триггера является параметром HttpRequestDataHttpRequest, пользовательские типы также могут быть привязаны к дополнительным параметрам с помощью Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute. Для использования этого атрибута требуется Microsoft.Azure.Functions.Worker.Extensions.Http версия 3.1.0 или более поздняя. Обратите внимание, что этот тип отличается от аналогичного атрибута Microsoft.AspNetCore.Mvc, а при использовании интеграции ASP.NET Core потребуется полный справочник или using оператор. В следующем примере показано, как использовать атрибут для получения только содержимого текста при наличии доступа к полной HttpRequestинтеграции с ASP.NET Core:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;

namespace AspNetIntegration
{
    public class BodyBindingHttpTrigger
    {
        [Function(nameof(BodyBindingHttpTrigger))]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [FromBody] Person person)
        {
            return new OkObjectResult(person);
        }
    }

    public record Person(string Name, int Age);
}

Настройка конечной точки HTTP

По умолчанию при создании функции для триггера HTTP маршрут для ее адресации имеет следующий вид:

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>

Этот маршрут можно настроить с помощью дополнительного свойства route привязки для вывода триггера HTTP. Для параметров можно использовать любое ограничение маршрута веб-API.

Следующий код функции принимает два параметра category и id в маршруте и записывает ответ, используя оба параметра.

[Function("HttpTrigger1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post",
Route = "products/{category:alpha}/{id:int?}")] HttpRequestData req, string category, int? id,
FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("HttpTrigger1");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = String.Format($"Category: {category}, ID: {id}");
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString(message);

    return response;
}

Параметры маршрута определяются с помощью параметра route заметки HttpTrigger. Следующий код функции принимает два параметра category и id в маршруте и записывает ответ, используя оба параметра.

package com.function;

import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;

public class HttpTriggerJava {
    public HttpResponseMessage<String> HttpTrigger(
            @HttpTrigger(name = "req",
                         methods = {"get"},
                         authLevel = AuthorizationLevel.FUNCTION,
                         route = "products/{category:alpha}/{id:int}") HttpRequestMessage<String> request,
            @BindingName("category") String category,
            @BindingName("id") int id,
            final ExecutionContext context) {

        String message = String.format("Category  %s, ID: %d", category, id);
        return request.createResponseBuilder(HttpStatus.OK).body(message).build();
    }
}

Например, следующий код TypeScript определяет route свойство для триггера HTTP с двумя параметрами и categoryid. В примере считываются параметры из запроса и возвращаются их значения в ответе.

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const category = request.params.category;
    const id = request.params.id;

    return { body: `Category: ${category}, ID: ${id}` };
}

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{category:alpha}/{id:int?}',
    handler: httpTrigger1,
});

Например, следующий код JavaScript определяет route свойство для триггера HTTP с двумя параметрами и categoryid. В примере считываются параметры из запроса и возвращаются их значения в ответе.

const { app } = require('@azure/functions');

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{category:alpha}/{id:int?}',
    handler: async (request, context) => {
        const category = request.params.category;
        const id = request.params.id;

        return { body: `Category: ${category}, ID: ${id}` };
    },
});

Например, следующий код определяет route свойство триггера HTTP с двумя параметрами и categoryid:

@app.function_name(name="httpTrigger")
@app.route(route="products/{category:alpha}/{id:int?}")

Параметры маршрута, объявленные в файле function.json, доступны как свойство объекта $Request.Params.

$Category = $Request.Params.category
$Id = $Request.Params.id

$Message = "Category:" + $Category + ", ID: " + $Id

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $Message
})

Контекст выполнения функции предоставляется с помощью параметра, объявленного как func.HttpRequest. Этот экземпляр позволяет функции обращаться к параметрам маршрута данных, значениям строк запросов и методам, которые позволяют возвращать HTTP-ответы.

После определения параметры маршрута становятся доступными в функции путем вызова метода route_params.

import logging

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    category = req.route_params.get('category')
    id = req.route_params.get('id')
    message = f"Category: {category}, ID: {id}"

    return func.HttpResponse(message)

При такой конфигурации функция доступна по приведенному ниже маршруту вместо исходного.

https://<APP_NAME>.azurewebsites.net/api/products/electronics/357

Эта конфигурация позволяет коду функции поддерживать два параметра в адресе, категории и идентификаторе. Дополнительные сведения о том, как параметры маршрута маркеризированы в URL-адресе, см. в разделе "Маршрутизация" в ASP.NET Core.

По умолчанию все маршруты функций начинаются с префикса api. Вы можете настроить или удалить этот префикс с помощью свойства extensions.http.routePrefix в файле host.json. В следующем примере префикс маршрута api удаляется. Он заменяется пустой строкой в файле host.json.

{
    "extensions": {
        "http": {
            "routePrefix": ""
        }
    }
}

Использование параметров маршрута

Каждой привязке доступны параметры маршрута, которые определяют шаблон route для функции. Например, если маршрут определен как "route": "products/{id}", привязка к хранилищу таблиц может использовать в конфигурации привязки значение параметра {id}.

В следующей конфигурации показано, как параметр {id} передается в rowKey привязки.

@app.table_input(arg_name="product", table_name="products", 
                 row_key="{id}", partition_key="products",
                 connection="AzureWebJobsStorage")
import { app, HttpRequest, HttpResponseInit, input, InvocationContext } from '@azure/functions';

const tableInput = input.table({
    connection: 'MyStorageConnectionAppSetting',
    partitionKey: 'products',
    tableName: 'products',
    rowKey: '{id}',
});

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    return { jsonBody: context.extraInputs.get(tableInput) };
}

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{id}',
    extraInputs: [tableInput],
    handler: httpTrigger1,
});
const { app, input } = require('@azure/functions');

const tableInput = input.table({
    connection: 'MyStorageConnectionAppSetting',
    partitionKey: 'products',
    tableName: 'products',
    rowKey: '{id}',
});

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{id}',
    extraInputs: [tableInput],
    handler: async (request, context) => {
        return { jsonBody: context.extraInputs.get(tableInput) };
    },
});
{
    "type": "table",
    "direction": "in",
    "name": "product",
    "partitionKey": "products",
    "tableName": "products",
    "rowKey": "{id}"
}

При использовании параметров маршрута для вашей функции автоматически создается invoke_URL_template. Клиенты могут использовать шаблон URL-адреса, чтобы понять, какие параметры им необходимо передать в URL-адресе при вызове вашей функции с использованием ее URL-адреса. Перейдите к одной из функций, выполняемых по протоколу HTTP, на портале Azure и выберите Получить URL-адрес функции.

Получить доступ к invoke_URL_template можно с помощью программных интерфейсов списка функций или команды Получить функцию в Azure Resource Manager.

HTTP-потоки (предварительная версия)

Теперь вы можете передавать запросы к конечной точке HTTP и ответы в Node.js приложениях-функциях версии 4. Дополнительные сведения см. в разделе HTTP-потоков.

Работа с удостоверениями клиентов

Если в приложении-функции используется аутентификация и авторизация Службы приложений, сведения об аутентифицированных клиентах можно посмотреть прямо в коде. Эта информация доступна в виде заголовков запросов, которые вставляет платформа.

Эти сведения также можно считывать из данных привязки. Эта возможность доступна только в среде выполнения Функций 2.x и более поздних версий. Кроме того, сейчас она доступна только для языков .NET.

Сведения о клиентах, прошедших проверку подлинности, доступны как ClaimsPrincipal, которые можно взять в контексте запроса, как показано в следующем примере.

Прошедший проверку подлинности пользователь доступен через заголовки HTTP.

Прошедший проверку подлинности пользователь доступен через заголовки HTTP.

Уровень авторизации

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

Значение уровня Description
анонимное — ключи API не требуются. Это значение по умолчанию, если уровень не задан специально.
function — требуется ключ API для конкретной функции.
admin — требуется главный ключ.
Значение уровня Description
анонимное — ключи API не требуются.
function — требуется ключ API для конкретной функции. Это значение по умолчанию, если уровень не задан специально.
admin — требуется главный ключ.

Ключи доступа к функции

Служба "Функции" позволяет использовать ключи, чтобы затруднить несанкционированный доступ к конечным точкам функции HTTP во время развертывания. Если уровень доступа HTTP для функции, активируемой HTTP, не имеет значение anonymous, запросы должны содержать ключ доступа API в этот запрос.

Хотя ключи предоставляют механизм безопасности по умолчанию, вы можете рассмотреть другие варианты для защиты конечной точки HTTP в рабочей среде. Например, не рекомендуется распространять общий секрет в общедоступных приложениях. Если ваша функция вызывается из общедоступного клиента, вы можете рассмотреть возможность реализации другого механизма безопасности. Дополнительные сведения см. в разделе Защита конечной точки HTTP в рабочей среде.

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

Области авторизации (уровень функции)

Существуют две области доступа для ключей уровня функции.

  • Функция: эти ключи применяются только к определенным функциям, в которых они определены. Если такой ключ используется в качестве ключа API, он предоставляет доступ только к определенной функции.

  • Узел. Ключи с область узла можно использовать для доступа ко всем функциям в приложении-функции. Если такой ключ используется в качестве ключа API, он предоставляет доступ к любой функции в приложении-функции.

Каждый ключ называется ссылкой и имеется ключ по умолчанию (по умолчанию) на уровне функции и узла. Ключи функций имеют приоритет над ключами узла. Если определены два ключа с одним именем, всегда используется ключ функции.

Главный ключ (уровень администратора)

У каждого приложения-функции также есть ключ узла уровня администратора с именем _master. Кроме предоставления доступа на уровне узла ко всем функциям в приложении, главный ключ также предоставляет административный доступ к REST API среды выполнения. Этот ключ нельзя отменить. При задании уровня доступа admin запросы должны использовать главный ключ. Использование любого другого ключа приведет к ошибке доступа.

Внимание

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

Получение ключей

Ключи хранятся в Azure в составе приложения-функции в зашифрованном виде. Чтобы просмотреть ключи, создать новые или сменить значения ключей, откройте на портале Azure нужную функцию, выполняемую по протоколу HTTP, и выберите Ключи функции.

Также можно управлять ключами узлов. Перейдите к приложению-функции на портале Azure и выберите Ключи приложения.

Можно получить ключи функции и ключи узла с помощью программных интерфейсов Azure Resource Manager. Существуют программные интерфейсы Список функциональных ключей и Списка ключей узлов, а при использовании слотов развертывания эквивалентными программными интерфейсами являются Список слотов ключей функций и Список слотов ключей узлов.

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

Ключи функций и узлов можно удалять с помощью программных интерфейсов Удалить секрет функции, Удалить слот секрета функции, Удалить секрет узла и Удалить слот секрета узла.

Также можно использовать устаревшие программные интерфейсы управления ключами для получения ключей функций, но вместо этого рекомендуется использовать программные интерфейсы Azure Resource Manager.

Проверка подлинности с помощью ключа API

Большинству шаблонов триггеров HTTP требуется ключ API в запросе. Поэтому HTTP-запрос обычно выглядит как следующий URL-адрес:

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>

Ключ можно передать в переменной строки запроса с именем code, как показано выше. Его также можно включить в заголовок HTTP x-functions-key. Значением ключа может быть любой ключ функции, определенный для запрашиваемой функции, или любой ключ узла.

Вы можете разрешить анонимные запросы, не требующие наличие ключей. Вы также можете указать, что используется главный ключ. Уровень авторизации по умолчанию можно изменить с помощью свойства authLevel в объекте JSON для привязки. Дополнительные сведения см. в разделе Конфигурация триггера.

Примечание.

При локальном выполнении функций авторизация всегда отключается, независимо от указанного параметра уровня аутентификации. После публикации в Azure в триггере применяется параметр authLevel. Ключи по-прежнему требуются при локальном выполнении в контейнере.

Защита конечной точки HTTP в рабочей среде

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

Включение проверки подлинности и авторизация службы приложений

Платформа Служба приложений позволяет использовать идентификатор Microsoft Entra и несколько сторонних поставщиков удостоверений для проверки подлинности клиентов. Эта стратегия позволяет реализовать пользовательские правила авторизации для функций и работать с информацией пользователя из кода функции. Дополнительные сведения см. в разделе Работа с удостоверениями клиентов и статье Проверка подлинности и авторизация в службе приложений Azure.

Использование службы Управления API Azure (APIM) для проверки подлинности запросов

APIM предоставляет широкий набор параметров безопасности API для входящих запросов. Дополнительные сведения см. в статье о политиках аутентификации службы "Управление API". С помощью службы "Управление API" можно настроить приложение-функцию на прием запросов только с IP-адреса вашего экземпляра этой службы. Дополнительные сведения см. в разделе Ограничения IP-адресов.

Развертывание приложения-функции в изолированной среде

Среда службы приложений Azure (ASE) предоставляет выделенную среду размещения, в которой можно выполнять функции. ASE позволяет настроить один интерфейсный шлюз, который можно использовать для аутентификации всех входящих запросов. Дополнительные сведения см. в статье Настройка брандмауэра веб-приложения (WAF) для среды службы приложений.

Веб-перехватчики

Примечание.

Режим веб-перехватчика доступен только для версии 1.x среды выполнения функций. Это изменение внесено для повышения производительности триггеров HTTP в версии 2.x и более поздних версиях.

В версии 1.x шаблоны веб-перехватчика обеспечивают дополнительную проверку полезных данных веб-перехватчика. В версии 2.x и более поздних версиях базовый триггер HTTP также работает, и мы рекомендуем использовать именно его для реализации веб-перехватчиков.

Тип веб-перехватчика

Свойство привязки webHookType указывает тип, если веб-перехватчик поддерживается функцией, который также диктует поддерживаемые полезные данные. Тип веб-перехватчика может принимать одно из следующих значений:

Значение типа Description
genericJson — конечная точка веб-перехватчика общего назначения без логики для конкретного поставщика. Этот параметр определяет, что принимаются только запросы HTTP POST с содержимым типа application/json.
github Функция отвечает на веб-перехватчики GitHub. Не используйте свойство authLevel с веб-перехватчиками GitHub.
slack Функция отвечает на веб-перехватчики Slack. Не используйте свойство authLevel вместе с веб-перехватчиками Slack.

При задании свойства webHookType не устанавливайте свойство methods в привязке.

Веб-перехватчики GitHub

Чтобы настроить ответ на вызовы веб-перехватчика GitHub, прежде всего создайте функцию с триггером HTTP, для которого свойство webHookType будет иметь значение github. Затем скопируйте его URL-адрес и ключ API в репозиторий GitHub, используя страницу Добавить веб-перехватчик.

Снимок экрана: добавление веб-перехватчика для функции.

Веб-перехватчики Slack

Webhook Slack создает маркер автоматически и не позволяет вам задать его, поэтому необходимо настроить ключ для конкретной функции с использованием маркера, предоставленного Slack. Ознакомьтесь с разделом Ключи авторизации.

Веб-перехватчики и ключи

Авторизация веб-перехватчика обрабатывается компонентом получателя веб-перехватчика, который входит в состав триггера HTTP. Механизм обработки различается в зависимости от типа веб-перехватчика. Каждый из этих механизмов зависит от ключей. По умолчанию используется ключ функции с именем default. Чтобы использовать другой ключ, необходимо настроить поставщик веб-перехватчика так, чтобы он отправлял имя ключа в составе запроса одним из следующих способов.

  • В строке запроса: поставщик передает имя ключа в параметре clientid строки запроса, например https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>.
  • В заголовке запроса: поставщик передает имя ключа в заголовке x-functions-clientid.

Типы содержимого

Передача двоичных данных и данных формы в функцию, отличную от C#, требует использования соответствующего заголовка типа содержимого. Поддерживаемые типы содержимого включают octet-stream для двоичных данных и составные типы.

Известные проблемы

В функциях, отличных от C#, запросы, отправляемые с типом содержимого image/jpeg, приводят к передаче значения stringв функцию. В подобных случаях можно вручную преобразовать значение string в массив байтов для доступа к необработанным двоичным данным.

Ограничения

Длина HTTP-запроса ограничена 100 МБ (104 857 600 байт), а длина URL-адреса —4 КБ (4096 байт). Эти ограничения задает элемент httpRuntimeфайла Web.config среды выполнения.

Если функция, которая использует триггер HTTP, выполняется дольше 230 секунд, допустимое время ожидания в Azure Load Balancer истекает и возвращается ошибка HTTP 502. Функция продолжит работу, но вернуть ответ HTTP будет невозможно. Для долго выполняющихся функций рекомендуем следовать асинхронным шаблонам и возвращать расположение, в котором можно проверить состояние запроса. Чтобы узнать, как долго может выполняться функция, см. раздел Масштабирование и размещение — план.

Следующие шаги