HTTP-Trigger in Azure Functions

Mit dem HTTP-Trigger können Sie eine Funktion mit einer HTTP-Anforderung aufrufen. Sie können einen HTTP-Trigger zum Erstellen von serverlosen APIs und zum Antworten auf Webhooks verwenden.

Der Standardrückgabewert für eine HTTP-ausgelöste Funktion ist:

  • HTTP 204 No Content bei leerem Hauptteil in Functions 2.x und höher
  • HTTP 200 OK bei leerem Hauptteil in Functions 1.x

Um die HTTP-Antwort zu ändern, konfigurieren Sie eine Ausgabebindung.

Weitere Informationen zu HTTP-Bindungen finden Sie in der Übersicht und Referenz für die Ausgabebindung.

Tipp

Wenn Sie die HTTP- oder WebHook-Bindungen verwenden möchten, vermeiden Sie die Portauslastung, die durch nicht ordnungsgemäße Instanziierung von HttpClient verursacht werden kann. Weitere Informationen finden Sie unter How to manage connections in Azure Functions (Verwalten von Verbindungen in Azure Functions).

Beispiel

Eine C#-Funktion kann mit einem der folgenden C#-Modi erstellt werden:

  • In-Process-Klassenbibliothek: Kompilierte C#-Funktion, die im gleichen Prozess wie die Functions-Runtime ausgeführt wird.
  • Klassenbibliothek in einem isolierten Prozess: Kompilierte C#-Funktion, die in einem Prozess ausgeführt wird, der von der Runtime isoliert ist. Ein isolierter Prozess ist erforderlich, um C#-Funktionen zu unterstützen, die unter .NET 5.0 ausgeführt werden.
  • C#-Skript: Wird hauptsächlich beim Erstellen von C#-Funktionen im Azure-Portal verwendet.

Der Code in diesem Artikel nutzt standardmäßig .NET Core-Syntax, die in Functions ab Version 2.x verwendet wird. Informationen zur 1.x-Syntax finden Sie in den 1.x-Functions-Vorlagen.

Das folgende Beispiel zeigt eine C#-Funktion, die in der Abfragezeichenfolge oder im Text der HTTP-Anforderung nach einem -Parameter sucht. Beachten Sie, dass der Rückgabewert für die Ausgabebindung verwendet wird, jedoch kein Attribut vom Rückgabewert erforderlich ist.

[FunctionName("HttpTriggerCSharp")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
    HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = String.Empty;
    using (StreamReader streamReader =  new  StreamReader(req.Body))
    {
        requestBody = await streamReader.ReadToEndAsync();
    }
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

Dieser Abschnitt enthält folgende Beispiele:

In den folgenden Beispielen wird die HTTP-Triggerbindung veranschaulicht.

Lesen eines Parameters aus der Abfragezeichenfolge

Dieses Beispiel liest einen Parameter namens id aus der Abfragezeichenfolge und verwendet ihn zum Erstellen eines JSON-Dokuments mit dem Inhaltstyp application/json, das an den Client zurückgegeben wird.

@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();
    }
}

Lesen des Hauptteils aus einer POST-Anforderung

Dieses Beispiel liest den Hauptteil einer POST-Anforderung als String und verwendet ihn zum Erstellen eines JSON-Dokuments mit dem Inhaltstyp application/json, das an den Client zurückgegeben wird.

    @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();
        }
    }

Lesen eines Parameters aus einer Route

Dieses Beispiel liest einen obligatorischen Parameter namens id sowie einen optionalen Parameter name aus dem Routenpfad und verwendet sie zum Erstellen eines JSON-Dokuments mit dem Inhaltstyp application/json, das an den Client zurückgegeben wird. T

@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();
    }
}

Lesen des POJO-Hauptteils aus einer POST-Anforderung

Hier sehen Sie den Code für die ToDoItem-Klasse, auf die in diesem Beispiel verwiesen wird:


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 + "}";
  }
}

In diesem Beispiel wird der Hauptteil einer POST-Anforderung gelesen. Der Anforderungstext wird automatisch in ein ToDoItem-Objekt deserialisiert und mit dem Inhaltstyp application/json an den Client zurückgegeben. Der Parameter ToDoItem wird durch die Functions-Runtime serialisiert, wenn er der Eigenschaft body der HttpMessageResponse.Builder-Klasse zugewiesen wird.

@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();
    }
}

Das folgende Beispiel zeigt eine Triggerbindung in einer Datei function.json sowie eine JavaScript-Funktion, die die Bindung verwendet. Die Funktion sucht in der Abfragezeichenfolge oder im Text der HTTP-Anforderung nach einem name-Parameter.

Die Datei function.json sieht wie folgt aus:

{
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}

Weitere Informationen zu diesen Eigenschaften finden Sie im Abschnitt Konfiguration.

Der JavaScript-Code sieht wie folgt aus:

module.exports = async function(context, req) {
    context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);

    if (req.query.name || (req.body && req.body.name)) {
        context.res = {
            // status defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

Das folgende Beispiel zeigt eine Triggerbindung in einer Datei function.json sowie eine PowerShell-Funktion. Die Funktion sucht in der Abfragezeichenfolge oder im Text der HTTP-Anforderung nach einem name-Parameter.

{
  "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
})

Das folgende Beispiel zeigt eine Triggerbindung in einer Datei function.json sowie eine Python-Funktion, die die Bindung verwendet. Die Funktion sucht in der Abfragezeichenfolge oder im Text der HTTP-Anforderung nach einem name-Parameter.

Die Datei function.json sieht wie folgt aus:

{
    "scriptFile": "__init__.py",
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "$return"
        }
    ]
}

Weitere Informationen zu diesen Eigenschaften finden Sie im Abschnitt Konfiguration.

Dies ist der Python-Code:

import logging
import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

Attributes

Sowohl von C#-Bibliotheken vom Typ In-Process als auch von C#-Bibliotheken vom Typ Isolierter Prozess wird HttpTriggerAttribute für die Triggerbindung verwendet. Das C#-Skript verwendet stattdessen eine Konfigurationsdatei „function.json“.

Bei In-Process-Funktionen unterstützt HttpTriggerAttribute die folgenden Parameter:

Parameter BESCHREIBUNG
AuthLevel Bestimmt, welche Schlüssel (sofern erforderlich) in der Anforderung vorhanden sein müssen, um die Funktion aufzurufen. Unterstützte Werte sind unter Autorisierungsstufe aufgeführt.
Methoden Ein Array der HTTP-Methoden, auf die diese Funktion antwortet. Wird dieses Array nicht angegeben, antwortet die Funktion auf alle HTTP-Methoden. Siehe Anpassen des HTTP-Endpunkts.
Route Definiert die Routenvorlage, mit der gesteuert wird, auf welche Anforderungs-URLs die Funktion antwortet. Wenn kein anderer Wert angegeben wird, lautet der Standardwert <functionname>. Weitere Informationen finden Sie unter Anpassen des HTTP-Endpunkts.
WebHookType Nur für die Laufzeit der Version 1.x unterstützt.

Konfiguriert den HTTP-Trigger so, dass er als Webhookempfänger für den angegebenen Anbieter fungiert. Unterstützte Werte sind unter WebHook-Typ aufgeführt.

Anmerkungen

Verwenden Sie in der Laufzeitbibliothek für Java-Funktionen die HttpTrigger-Anmerkung, die die folgenden Einstellungen unterstützt:

Konfiguration

Die folgende Tabelle gibt Aufschluss über die Triggerkonfigurationseigenschaften, die Sie in der Datei function.json festlegen (unterscheidet sich je nach Runtimeversion).

Die folgende Tabelle gibt Aufschluss über die Bindungskonfigurationseigenschaften, die Sie in der Datei function.json festlegen.

Eigenschaft von „function.json“ BESCHREIBUNG
type Erforderlich – muss auf httpTrigger festgelegt sein.
direction Erforderlich – muss auf in festgelegt sein.
name Erforderlich – der Variablenname, der im Funktionscode für die Anforderung oder den Anforderungstext verwendet wird.
authLevel Bestimmt, welche Schlüssel (sofern erforderlich) in der Anforderung vorhanden sein müssen, um die Funktion aufzurufen. Unterstützte Werte sind unter Autorisierungsstufe aufgeführt.
methods Ein Array der HTTP-Methoden, auf die diese Funktion antwortet. Wird dieses Array nicht angegeben, antwortet die Funktion auf alle HTTP-Methoden. Siehe Anpassen des HTTP-Endpunkts.
route Definiert die Routenvorlage, mit der gesteuert wird, auf welche Anforderungs-URLs die Funktion antwortet. Wenn kein anderer Wert angegeben wird, lautet der Standardwert <functionname>. Weitere Informationen finden Sie unter Anpassen des HTTP-Endpunkts.

Verwendung

In diesem Abschnitt wird beschrieben, wie Sie Ihre HTTP-Triggerfunktionsbindung konfigurieren.

Die HttpTrigger-Anmerkung sollte auf einen Methodenparameter eines der folgenden Typen angewendet werden:

  • HttpRequestMessage<T>.
  • Alle nativen Java-Typen wie „int“, „String“, „byte[]“.
  • Nullable-Werte unter Verwendung von „Optional“.
  • Beliebige POJO-Typen (Plain-Old Java Object).

Nutzlast

Der Triggereingabetyp wird entweder als HttpRequest oder als benutzerdefinierter Typ deklariert. Wenn Sie HttpRequest auswählen, erhalten Sie Vollzugriff auf das Anforderungsobjekt. Bei einem benutzerdefinierten Typ versucht die Laufzeit, den JSON-Anforderungstext zu analysieren, um die Objekteigenschaften festzulegen.

Anpassen des HTTP-Endpunkts

Wenn Sie eine Funktion für einen HTTP-Trigger erstellen, ist die Funktion mit einer Route der folgenden Form erreichbar:

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

Sie können diese Route mit der optionalen route-Eigenschaft in der Eingabebindung des HTTP-Triggers anpassen. Sie können für Ihre Parameter eine beliebige Web-API-Routeneinschränkung verwenden.

Der folgende C#-Funktionscode akzeptiert die beiden Parameter category und id in der Route und schreibt eine Antwort unter Verwendung dieser beiden Parameter.

[FunctionName("Function1")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "products/{category:alpha}/{id:int?}")] HttpRequest req,
string category, int? id, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var message = String.Format($"Category: {category}, ID: {id}");
    return (ActionResult)new OkObjectResult(message);
}

Routenparameter werden mithilfe der route-Einstellung der HttpTrigger-Anmerkung definiert. Der folgende Funktionscode akzeptiert die beiden Parameter category und id in der Route und schreibt eine Antwort unter Verwendung dieser beiden Parameter.

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();
    }
}

In diesem Beispiel wird mit der Datei function.json eine route-Eigenschaft für einen HTTP-Trigger mit den beiden Parametern category und id definiert:

{
    "bindings": [
    {
        "type": "httpTrigger",
        "name": "req",
        "direction": "in",
        "methods": [ "get" ],
        "route": "products/{category:alpha}/{id:int?}"
    },
    {
        "type": "http",
        "name": "res",
        "direction": "out"
    }
    ]
}

Die Functions-Runtime stellt den Anforderungstext aus dem context-Objekt bereit. Im folgenden Beispiel wird veranschaulicht, wie Sie Routenparameter aus context.bindingData lesen.

module.exports = async function (context, req) {

    var category = context.bindingData.category;
    var id = context.bindingData.id;
    var message = `Category: ${category}, ID: ${id}`;

    context.res = {
        body: message;
    }
}

Routenparameter, die in der Datei function.json deklariert werden, sind als Eigenschaft des -Objekts zugänglich.

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

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

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

Der Funktionsausführungskontext wird über einen als func.HttpRequest deklarierten Parameter bereitgestellt. Diese Instanz ermöglicht einer Funktion den Zugriff auf Datenroutenparameter, Abfragezeichenfolgenwerte und Methoden, mit denen Sie HTTP-Antworten zurückgeben können.

Nach der Definition sind die Routenparameter für die Funktion verfügbar, indem die route_params-Methode aufgerufen wird.

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)

Mit dieser Konfiguration ist die Funktion jetzt über die folgende Route erreichbar, anstatt über die ursprüngliche Route.

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

Diese Konfiguration gestattet dem Funktionscode, zwei Parameter in der Adresse unterstützen: category und id. Weitere Informationen dazu, wie Routenparameter in einer URL mit einem Token versehen werden, finden Sie unter Routing in ASP.NET Core.

Standardmäßig verfügen alle Funktionsrouten über das Präfix api. Sie können das Präfix auch mit der extensions.http.routePrefix-Eigenschaft in der Datei extensions.http.routePrefix anpassen oder entfernen. Im folgenden Beispiel wird das Routenpräfix api entfernt, indem in der Datei host.json eine leere Zeichenfolge als Präfix verwendet wird.

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

Verwenden von Routenparametern

Routenparameter, die das Muster route einer Funktion definiert haben, sind für jede Bindung verfügbar. Wenn Sie beispielsweise eine Route als "route": "products/{id}" definiert haben, kann eine Tabellenspeicherbindung den Wert des Parameters {id} in der Bindungskonfiguration verwenden.

Die folgende Konfiguration zeigt, wie der Parameter {id} an das rowKey-Element der Bindung übergeben wird:

{
    "type": "table",
    "direction": "in",
    "name": "product",
    "partitionKey": "products",
    "tableName": "products",
    "rowKey": "{id}"
}

Wenn Sie Routenparameter verwenden, wird automatisch eine invoke_URL_template für Ihre Funktion erstellt. Die Clients können die URL-Vorlage verwenden, um zu wissen, welche Parameter sie beim Aufrufen Ihrer Funktion an die URL übergeben müssen. Navigieren Sie im Azure-Portal zu einer der durch HTTP ausgelösten Funktionen, und wählen Sie Funktions-URL abrufen aus.

Sie können programmgesteuert auf die invoke_URL_template zugreifen, indem Sie die Azure Resource Manager-APIs invoke_URL_template oder Funktionen abrufen verwenden.

Arbeiten mit Clientidentitäten

Wenn Ihre Funktions-App App Service-Authentifizierung/-Autorisierung verwendet, können Sie Informationen über authentifizierte Clients aus Ihrem Code anzeigen. Diese Informationen sind als von der Plattform eingefügter Anforderungsheader verfügbar.

Sie können diese Informationen auch aus Datenbindungen auslesen. Diese Funktion ist nur für die Functions-Runtime 2.x und höher verfügbar. Sie ist derzeit auch nur für .NET-Sprachen verfügbar.

Informationen zu authentifizierten Clients sind als ClaimsPrincipal verfügbar, der als Teil des Anforderungskontexts verfügbar ist, wie im folgenden Beispiel gezeigt:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

public static IActionResult Run(HttpRequest req, ILogger log)
{
    ClaimsPrincipal identities = req.HttpContext.User;
    // ...
    return new OkObjectResult();
}

Alternativ kann „ClaimsPrincipal“ einfach als zusätzlicher Parameter in die Funktionssignatur aufgenommen werden:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using Newtonsoft.Json.Linq;

public static void Run(JObject input, ClaimsPrincipal principal, ILogger log)
{
    // ...
    return;
}

Der authentifizierte Benutzer ist über HTTP-Header verfügbar.

Autorisierungsstufe

Die Autorisierungsstufe ist ein Zeichenfolgenwert, der die Art des Autorisierungsschlüssels angibt, der für den Zugriff auf den Funktionsendpunkt erforderlich ist. Für eine durch HTTP ausgelöste Funktion kann die Autorisierungsstufe einen der folgenden Werte aufweisen:

Level-Wert Beschreibung
anonymous Es ist kein API-Schlüssel erforderlich.
Funktion Es ist ein funktionsspezifischer API-Schlüssel erforderlich. Dies ist der Standardwert, wenn keine spezifische Stufe festgelegt ist.
admin Der Hauptschlüssel ist erforderlich.

Funktionszugriffsschlüssel

Mit Functions können Sie Schlüssel verwenden, wodurch der Zugriff auf Ihre HTTP-Funktionsendpunkte während der Entwicklung erschwert wird. Sofern die HTTP-Zugriffsebene für eine über HTTP ausgelöste Funktion nicht auf anonymous festgelegt ist, müssen Anforderungen einen API-Zugriffsschlüssel in der Anforderung enthalten.

Schlüssel bieten zwar einen Standardsicherheitsmechanismus, für den Schutz eines HTTP-Endpunkts in der Produktion sollten jedoch gegebenenfalls zusätzliche Optionen in Erwägung gezogen werden. So ist es beispielsweise in der Regel nicht empfehlenswert, den gemeinsamen geheimen Schlüssel in öffentlichen Apps zu verteilen. Wenn Ihre Funktion über einen öffentlichen Client aufgerufen wird, empfiehlt es sich gegebenenfalls, einen anderen Sicherheitsmechanismus zu implementieren. Weitere Informationen hierzu finden Sie unter Schützen eines HTTP-Endpunkts in einer Produktionsumgebung.

Wenn Sie Ihre Funktionsschlüsselwerte erneuern, müssen die aktualisierten Schlüsselwerte manuell an alle Clients verteilt werden, von denen Ihre Funktion aufgerufen wird.

Autorisierungsbereiche (Funktionsebene)

Es gibt zwei Zugriffsbereiche für Schlüssel auf Funktionsebene:

  • Funktion: Diese Schlüssel gelten nur für die Funktionen, für die sie definiert sind. Bei Verwendung als API-Schlüssel ermöglichen diese nur Zugriff auf diese spezielle Funktion.

  • Host: Schlüssel mit einem Hostbereich können für den Zugriff auf alle Funktionen in der Funktions-App verwendet werden. Bei Verwendung als API-Schlüssel ermöglichen diese Zugriff auf jede Funktion in der Funktionen-App.

Jeder Schlüssel ist zu Referenzzwecken benannt. Auf Funktions- und Hostebene gibt es einen Standardschlüssel (mit dem Namen „default“). Funktionsschlüssel haben Vorrang vor Hostschlüsseln. Wenn zwei Schlüssel mit dem gleichen Namen definiert wurden, wird immer der Funktionsschlüssel verwendet.

Hauptschlüssel (Administratorebene)

Jede Funktions-App verfügt außerdem über einen Hostschlüssel auf Administratorebene mit dem Namen _master. Zusätzlich zur Bereitstellung des Zugriffs auf Hostebene auf alle Funktionen in der App bietet der Hauptschlüssel auch administrativen Zugriff auf die Laufzeit-REST-APIs. Dieser Schlüssel kann nicht widerrufen werden. Wenn Sie die Zugriffsebene admin festlegen, muss für Anforderungen der Hauptschlüssel verwendet werden. Alle anderen Schlüssel führen zu einem Zugriffsfehler.

Achtung

Aufgrund der erhöhten Berechtigungen, die der Hauptschlüssel in Ihrer Funktions-App gewährt, sollten Sie diesen Schlüssel nicht für Dritte freigeben oder in nativen Clientanwendungen verteilen. Gehen Sie umsichtig vor, wenn Sie die Zugriffsebene „Administrator“ auswählen.

Abrufen von Schlüsseln

Schlüssel werden als Teil Ihrer Funktionen-App in Azure gespeichert und sind im Ruhezustand verschlüsselt. Um vorhandene Schlüssel anzuzeigen, neue Schlüssel zu erstellen oder Schlüsseln neue Werte zuzuweisen, navigieren Sie im Azure-Portal zu einer Ihrer über HTTP ausgelösten Funktionen, und wählen Sie Funktionsschlüssel aus.

Sie können auch Hostschlüssel verwalten. Navigieren Sie im Azure-Portal zur Funktions-App, und wählen Sie App-Schlüssel aus.

Sie können Funktions- und Hostschlüssel programmgesteuert über die Azure Resource Manager-APIs abrufen. Es gibt APIs zum Auflisten von Funktionsschlüsseln und zum Auflisten von Hostschlüsseln. Wenn Sie Bereitstellungsslots verwenden, nutzen Sie entsprechend die APIs zum Auflisten von Funktionsschlüsseln für Slots bzw. zum Auflisten von Hostschlüsseln für Slots.

Sie können mit den APIs Funktionsgeheimnis erstellen oder aktualisieren, Funktionsgeheimnis für Slots erstellen oder aktualisieren, Hostgeheimnis erstellen oder aktualisieren und Hostgeheimnis für Slots erstellen oder aktualisieren auch programmgesteuert neue Funktions- und Hostschlüssel erstellen.

Löschen können Sie Funktions- und Hostschlüssel programmgesteuert über die APIs Funktionsgeheimnis löschen, Funktionsgeheimnis für Slots löschen, Hostgeheimnis löschen und Hostgeheimnis für Slots löschen.

Sie können auch die Legacy-APIs für die Schlüsselverwaltung verwenden, um Funktionsschlüssel abzurufen. Es wird jedoch empfohlen, die Azure Resource Manager-APIs zu verwenden.

Autorisierung per API-Schlüssel

Für die meisten HTTP-Triggervorlagen muss in der Anforderung ein API-Schlüssel vorhanden sein. Ihre HTTP-Anforderung sieht daher normalerweise wie folgende URL aus:

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

Der Schlüssel kann in einer Abfragezeichenfolgenvariablen namens code (wie oben zu sehen) enthalten sein. Er kann auch in einem x-functions-key-HTTP-Header enthalten sein. Der Wert des Schlüssels kann ein beliebiger für die Funktion definierter Funktionsschlüssel oder ein beliebiger Hostschlüssel sein.

Sie können anonyme Anforderungen zulassen, die keine Schlüssel erfordern. Sie können auch anfordern, dass der Hauptschlüssel verwendet wird. Zum Ändern der Standardautorisierungsstufe verwenden Sie die authLevel-Eigenschaft in der Bindungs-JSON. Weitere Informationen finden Sie unter Trigger: Konfiguration.

Hinweis

Beim lokalen Ausführen von Funktionen ist die Autorisierung unabhängig von der festgelegten Autorisierungsebene deaktiviert. Die authLevel-Einstellung in Ihrem Trigger wird nach der Veröffentlichung in Azure angewendet. Schlüssel sind auch bei lokaler Ausführung in einem Container weiterhin erforderlich.

Schützen eines HTTP-Endpunkts in einer Produktionsumgebung

Wenn Sie Ihre Funktionsendpunkte in einer Produktionsumgebung umfassend schützen möchten, sollten Sie eine der folgenden Sicherheitsoptionen auf Funktions-App-Ebene implementieren. Wenn Sie eine dieser Sicherheitsmethoden auf Funktions-App-Ebene verwenden, sollten Sie die Autorisierungsebene der über HTTP ausgelösten Funktion auf anonymous festlegen.

Aktivieren der App Service-Authentifizierung/-Autorisierung

Die App Service-Plattform ermöglicht die Verwendung von Azure Active Directory (AAD) sowie von verschiedenen anderen Identitätsanbietern zum Authentifizieren von Clients. Sie können diese Strategie zum Implementieren von benutzerdefinierten Autorisierungsregeln für Ihre Funktionen sowie Benutzerinformationen aus Ihrem Funktionscode verwenden. Weitere Informationen finden Sie unter Authentifizierung und Autorisierung in Azure App Service und Arbeiten mit Clientidentitäten.

Verwenden von Azure API Management (APIM) zum Authentifizieren von Anforderungen

APIM stellt verschiedene API-Sicherheitsoptionen für eingehende Anforderungen bereit. Weitere Informationen hierzu finden Sie unter API Management-Authentifizierungsrichtlinien. Wenn APIM vorhanden ist, können Sie Ihre Funktions-App so konfigurieren, dass Anforderungen nur von den IP-Adressen Ihrer APIM-Instanz angenommen werden. Weitere Informationen hierzu finden Sie unter Einschränkungen für IP-Adressen.

Isoliertes Bereitstellen Ihrer Funktions-App

Die Azure App Service-Umgebung (ASE) stellt eine spezielle Hostingumgebung bereit, in der Sie Ihre Funktionen ausführen können. Mit ASE können Sie ein Front-End-Gateway konfigurieren, das Sie zum Authentifizieren aller eingehenden Anforderungen verwenden können. Weitere Informationen hierzu finden Sie unter Konfigurieren einer Web Application Firewall (WAF) für eine App Service-Umgebung.

webhooks

Hinweis

Der Webhookmodus ist nur für die Version 1.x der Functions-Laufzeit verfügbar. Diese Änderung wurde vorgenommen, um die Leistung von HTTP-Triggern in Version 2.x und höheren Versionen zu verbessern.

In Version 1.x stellen Webhookvorlagen zusätzliche Überprüfungsoptionen für Webhooknutzlasten bereit. In Version 2.x und höheren Versionen kann der HTTP-Basistrigger weiterhin verwendet werden. Zudem wird er für Webhooks empfohlen.

WebHook-Typ

Die Bindungseigenschaft webHookType gibt den Typ an, wenn die Funktion Webhooks unterstützt. Dieser Wert gibt auch die unterstützte Payload vor. Der Webhooktyp kann folgende Werte annehmen:

Typwert Beschreibung
genericJson Ein allgemeiner Webhookendpunkt ohne Logik für einen bestimmten Anbieter. Diese Einstellung beschränkt Anforderungen auf solche, die HTTP POST verwenden und den Inhaltstyp application/json aufweisen.
github Die Funktion antwortet auf GitHub-Webhooks. Verwenden Sie die authLevel-Eigenschaft nicht mit GitHub-Webhooks.
slack Die Funktion antwortet auf Slack-Webhooks. Verwenden Sie die authLevel-Eigenschaft nicht mit Slack-Webhooks.

Bei Festlegung der webHookType-Eigenschaft darf die methods-Eigenschaft nicht ebenfalls für die Bindung festgelegt werden.

GitHub-Webhooks

Erstellen Sie zum Antworten auf GitHub-Webhooks zuerst eine Funktion mit einem HTTP-Trigger, und legen Sie die webHookType-Eigenschaft auf fest. Kopieren Sie dann die URL und den API-Schlüssel auf die Seite Webhook hinzufügen Ihres GitHub-Repositorys.

Screenshot that shows how to add a webhook for your function.

Slack-Webhooks

Der Slack-Webhook lässt Sie das Token nicht angeben, sondern generiert es für Sie. Daher müssen Sie einen funktionsspezifischen Schlüssel mit dem Token aus Slack konfigurieren. Weitere Informationen finden Sie unter Autorisierungsschlüssel.

Webhooks und Schlüssel

Die Webhookautorisierung wird von der Empfangskomponente für Webhooks verarbeitet, die zum HTTP-Trigger gehört. Der Mechanismus variiert je nach Webhooktyp. Für jeden Mechanismus wird ein Schlüssel benötigt. Standardmäßig wird der Funktionsschlüssel namens „default“ verwendet. Um einen anderen Schlüssel zu verwenden, konfigurieren Sie den Webhookanbieter, sodass der Schlüsselname auf eine der folgenden Arten mit der Anforderung gesendet wird:

  • Abfragezeichenfolge: Der Anbieter übergibt den Schlüsselnamen im -Abfragezeichenfolgenparameter, z. B. https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>.
  • Anforderungsheader: Der Anbieter übergibt den Schlüsselnamen im -Header.

Inhaltstypen

Bei der Übergabe von Binär- und Formulardaten an eine C#-fremde Funktion muss der passende Content-Type-Header verwendet werden. Zu den unterstützten Inhaltstypen zählt octet-stream für Binärdaten und octet-stream.

Bekannte Probleme

In C#-fremden Funktionen wird bei Anforderungen, die mit dem Inhaltstyp image/jpeg gesendet werden, ein Wert vom Typ string an die Funktion übergeben. In einem solchen Fall können Sie den Wert vom Typ string manuell in ein Bytearray konvertieren, um auf die unformatierten Binärdaten zuzugreifen.

Einschränkungen

Die Länge der HTTP-Anforderung ist auf 100 MB (104.857.600 Bytes) und die URL-Länge auf 4 KB (4.096 Bytes) beschränkt. Diese Grenzwerte werden durch das httpRuntime-Element der Datei httpRuntime der Runtime angegeben.

Wenn eine Funktion, die den HTTP-Trigger verwendet, nicht innerhalb von etwa 230 Sekunden abgeschlossen ist, tritt bei Azure Load Balancer ein Timeout auf, und es wird ein HTTP 502-Fehler zurückgegeben. Die Funktion wird weiterhin ausgeführt, kann aber keine HTTP-Antwort zurückgeben. Bei Funktionen mit langer Ausführungsdauer empfiehlt es sich, asynchrone Muster zu befolgen und einen Speicherort zurückzugeben, von dem aus Sie den Status der Anforderung pingen können. Informationen dazu, wie lang eine Funktion ausgeführt werden kann, finden Sie unter Skalierung und Hosting – Verbrauchsplan.

Nächste Schritte