添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft Edge More info about Internet Explorer and Microsoft Edge

The HTTP trigger lets you invoke a function with an HTTP request. You can use an HTTP trigger to build serverless APIs and respond to webhooks.

The default return value for an HTTP-triggered function is:

  • HTTP 204 No Content with an empty body in Functions 2.x and higher
  • HTTP 200 OK with an empty body in Functions 1.x
  • To modify the HTTP response, configure an output binding .

    For more information about HTTP bindings, see the overview and output binding reference .

    If you plan to use the HTTP or WebHook bindings, plan to avoid port exhaustion that can be caused by improper instantiation of HttpClient . For more information, see How to manage connections in Azure Functions .

    Important

    This article uses tabs to support multiple versions of the Node.js programming model. The v4 model is generally available and is designed to have a more flexible and intuitive experience for JavaScript and TypeScript developers. Learn more about the differences between v3 and v4 in the migration guide .

    Azure Functions supports two programming models for Python. The way that you define your bindings depends on your chosen programming model.

    A C# function can be created by using one of the following C# modes:

  • Isolated worker model : Compiled C# function that runs in a worker process that's isolated from the runtime. Isolated worker process is required to support C# functions running on LTS and non-LTS versions .NET and the .NET Framework. Extensions for isolated worker process functions use Microsoft.Azure.Functions.Worker.Extensions.* namespaces.
  • In-process model : Compiled C# function that runs in the same process as the Functions runtime. In a variation of this model, Functions can be run using C# scripting , which is supported primarily for C# portal editing. Extensions for in-process functions use Microsoft.Azure.WebJobs.Extensions.* namespaces.
  • The code in this article defaults to .NET Core syntax, used in Functions version 2.x and higher. For information on the 1.x syntax, see the 1.x functions templates .

    Isolated worker model In-process model

    The following example shows an HTTP trigger that returns a "hello world" response as an HttpResponseData object:

    [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;

    The following example shows an HTTP trigger that returns a "hello, world" response as an IActionResult , using ASP.NET Core integration in .NET Isolated :

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

    The following example shows a C# function that looks for a name parameter either in the query string or the body of the HTTP request. Notice that the return value is used for the output binding, but a return value attribute isn't required.

    [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");
    
  • Read parameter from the query string
  • Read body from a POST request
  • Read parameter from a route
  • Read POJO body from a POST request
  • The following examples show the HTTP trigger binding.

    Read parameter from the query string

    This example reads a parameter, named id, from the query string, and uses it to build a JSON document returned to the client, with content type 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();
    

    Read body from a POST request

    This example reads the body of a POST request, as a String, and uses it to build a JSON document returned to the client, with content type 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();
    

    Read parameter from a route

    This example reads a mandatory parameter, named id, and an optional parameter name from the route path, and uses them to build a JSON document returned to the client, with content type application/json. 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();
    

    Read POJO body from a POST request

    Here is the code for the ToDoItem class, referenced in this example:

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

    This example reads the body of a POST request. The request body gets automatically de-serialized into a ToDoItem object, and is returned to the client, with content type application/json. The ToDoItem parameter is serialized by the Functions runtime as it is assigned to the body property of the HttpMessageResponse.Builder class.

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

    The following example shows an HTTP trigger TypeScript function. The function looks for a name parameter either in the query string or the body of the HTTP request.

    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,

    TypeScript samples are not documented for model v3.

    The following example shows an HTTP trigger JavaScript function. The function looks for a name parameter either in the query string or the body of the HTTP request.

    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}!` };

    The following example shows a trigger binding in a function.json file and a JavaScript function that uses the binding. The function looks for a name parameter either in the query string or the body of the HTTP request.

    Here's the function.json file:

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

    The configuration section explains these properties.

    Here's the JavaScript code:

    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"
    

    The following example shows a trigger binding in a function.json file and a PowerShell function. The function looks for a name parameter either in the query string or the body of the HTTP request.

    "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
    

    The following example shows a trigger binding and a Python function that uses the binding. The function looks for a name parameter either in the query string or the body of the HTTP request. The example depends on whether you use the v1 or v2 Python programming model.

    @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

    The configuration section explains these properties.

    Here's the 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:
                req_body = req.get_json()
            except ValueError:
            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
    AuthLevel
    Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level.
    Methods
    An array of the HTTP methods to which the function  responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint.
    Route
    Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname>. For more information, see customize the HTTP endpoint.
    AuthLevel
    Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level.
    Methods
    An array of the HTTP methods to which the function  responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint.
    Route
    Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname>. For more information, see customize the HTTP endpoint.
    WebHookType
    Supported only for the version 1.x runtime.

    Configures the HTTP trigger to act as a webhook receiver for the specified provider. For supported values, see WebHook type. route Route for the http endpoint, if None, it will be set to function name if present or user defined python function name. trigger_arg_name Argument name for HttpRequest, defaults to 'req'. binding_arg_name Argument name for HttpResponse, defaults to '$return'. methods A tuple of the HTTP methods to which the function responds. auth_level Determines what keys, if any, need to be present on the request in order to invoke the function.

    For Python functions defined by using function.json, see the Configuration section.

    Annotations

    In the Java functions runtime library, use the HttpTrigger annotation, which supports the following settings:

  • authLevel
  • dataType
  • methods
  • route
  • Configuration

    Applies only to the Python v1 programming model.

    authLevel Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level. methods An array of the HTTP methods to which the function responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint. route Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname>. For more information, see customize the HTTP endpoint. authLevel Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level. methods An array of the HTTP methods to which the function responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint. route Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname>. For more information, see customize the HTTP endpoint. authLevel Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level. methods An array of the HTTP methods to which the function responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint. route Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname>. For more information, see customize the HTTP endpoint. authLevel Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level. methods An array of the HTTP methods to which the function responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint. route Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname>. For more information, see customize the HTTP endpoint. webHookType Configures the HTTP trigger to act as a webhook receiver for the specified provider. For supported values, see WebHook type.

    This section details how to configure your HTTP trigger function binding.

    The HttpTrigger annotation should be applied to a method parameter of one of the following types:

  • HttpRequestMessage<T>.
  • Any native Java types such as int, String, byte[].
  • Nullable values using Optional.
  • Any plain-old Java object (POJO) type.
  • Payload

    Isolated worker model In-process model HttpRequest Use of this type requires that the app is configured with ASP.NET Core integration in .NET Isolated.
    This gives you full access to the request object and overall HttpContext. A custom type When the body of the request is JSON, the runtime will try to parse it to set the object properties.

    When using HttpRequestData or HttpRequest, custom types can also be bound to additional parameters using Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute. Use of this attribute requires Microsoft.Azure.Functions.Worker.Extensions.Http version 3.1.0 or later. Note that this is a different type than the similar attribute in Microsoft.AspNetCore.Mvc, and when using ASP.NET Core integration, you will need a fully qualified reference or using statement. The following example shows how to use the attribute to get just the body contents while still having access to the full HttpRequest, using the ASP.NET Core integration:

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

    Customize the HTTP endpoint

    By default when you create a function for an HTTP trigger, the function is addressable with a route of the form:

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

    You can customize this route using the optional route property on the HTTP trigger's input binding. You can use any Web API Route Constraint with your parameters.

    The following function code accepts two parameters category and id in the route and writes a response using both parameters.

    [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;
    

    The following C# function code accepts two parameters category and id in the route and writes a response using both parameters.

    [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);
    

    Route parameters are defined using the route setting of the HttpTrigger annotation. The following function code accepts two parameters category and id in the route and writes a response using both parameters.

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

    As an example, the following TypeScript code defines a route property for an HTTP trigger with two parameters, category and id. The example reads the parameters from the request and returns their values in the response.

    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,

    TypeScript samples are not documented for model v3.

    As an example, the following JavaScript code defines a route property for an HTTP trigger with two parameters, category and id. The example reads the parameters from the request and returns their values in the response.

    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}` };

    As an example, the following function.json file defines a route property for an HTTP trigger with two parameters, category and id:

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

    The Functions runtime provides the request body from the context object. The following example shows how to read route parameters from context.bindingData.

    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;
    

    Route parameters declared in the function.json file are accessible as a property of the $Request.Params object.

    $Category = $Request.Params.category
    $Id = $Request.Params.id
    $Message = "Category:" + $Category + ", ID: " + $Id
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = [HttpStatusCode]::OK
        Body = $Message
    

    The function execution context is exposed via a parameter declared as func.HttpRequest. This instance allows a function to access data route parameters, query string values and methods that allow you to return HTTP responses.

    Once defined, the route parameters are available to the function by calling the route_params method.

    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)
    

    Using this configuration, the function is now addressable with the following route instead of the original route.

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

    This configuration allows the function code to support two parameters in the address, category and id. For more information on how route parameters are tokenized in a URL, see Routing in ASP.NET Core.

    By default, all function routes are prefixed with api. You can also customize or remove the prefix using the extensions.http.routePrefix property in your host.json file. The following example removes the api route prefix by using an empty string for the prefix in the host.json file.

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

    Using route parameters

    Route parameters that defined a function's route pattern are available to each binding. For example, if you have a route defined as "route": "products/{id}" then a table storage binding can use the value of the {id} parameter in the binding configuration.

    The following configuration shows how the {id} parameter is passed to the binding's 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,
    

    TypeScript samples are not documented for model v3.

    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) }; "name": "product", "connection": "MyStorageConnectionAppSetting", "partitionKey": "products", "tableName": "products", "rowKey": "{id}"

    When you use route parameters, an invoke_URL_template is automatically created for your function. Your clients can use the URL template to understand the parameters they need to pass in the URL when calling your function using its URL. Navigate to one of your HTTP-triggered functions in the Azure portal and select Get function URL.

    You can programmatically access the invoke_URL_template by using the Azure Resource Manager APIs for List Functions or Get Function.

    Working with client identities

    If your function app is using App Service Authentication / Authorization, you can view information about authenticated clients from your code. This information is available as request headers injected by the platform.

    You can also read this information from binding data. This capability is only available to the Functions runtime in 2.x and higher. It is also currently only available for .NET languages.

    Information regarding authenticated clients is available as a ClaimsPrincipal, which is available as part of the request context as shown in the following example:

    Isolated worker model In-process model using System.Security.Claims; public static IActionResult Run(HttpRequest req, ILogger log) ClaimsPrincipal identities = req.HttpContext.User; // ... return new OkObjectResult();

    Alternatively, the ClaimsPrincipal can simply be included as an additional parameter in the function signature:

    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;
    function
    A function-specific API key is required. This is the default value when a level isn't specifically set.
    admin
    The master key is required.
    

    Function access keys

    Functions lets you use keys to make it harder to access your HTTP function endpoints during development. Unless the HTTP access level on an HTTP triggered function is set to anonymous, requests must include an API access key in the request.

    While keys provide a default security mechanism, you may want to consider other options to secure an HTTP endpoint in production. For example, it's not a good practice to distribute shared secret in public apps. If your function is being called from a public client, you may want to consider implementing another security mechanism. To learn more, see Secure an HTTP endpoint in production.

    When you renew your function key values, you must manually redistribute the updated key values to all clients that call your function.

    Authorization scopes (function-level)

    There are two access scopes for function-level keys:

  • Function: These keys apply only to the specific functions under which they're defined. When used as an API key, these only allow access to that function.

  • Host: Keys with a host scope can be used to access all functions within the function app. When used as an API key, these allow access to any function within the function app.

    Each key is named for reference, and there's a default key (named "default") at the function and host level. Function keys take precedence over host keys. When two keys are defined with the same name, the function key is always used.

    Master key (admin-level)

    Each function app also has an admin-level host key named _master. In addition to providing host-level access to all functions in the app, the master key also provides administrative access to the runtime REST APIs. This key can't be revoked. When you set an access level of admin, requests must use the master key; any other key results in access failure.

    Caution

    Due to the elevated permissions in your function app granted by the master key, you shouldn't share this key with third parties or distribute it in native client applications. Use caution when choosing the admin access level.

    Obtaining keys

    Keys are stored as part of your function app in Azure and are encrypted at rest. To view your keys, create new ones, or roll keys to new values, navigate to one of your HTTP-triggered functions in the Azure portal and select Function Keys.

    You can also manage host keys. Navigate to the function app in the Azure portal and select App keys.

    You can obtain function and host keys programmatically by using the Azure Resource Manager APIs. There are APIs to List Function Keys and List Host Keys, and when using deployment slots the equivalent APIs are List Function Keys Slot and List Host Keys Slot.

    You can also create new function and host keys programmatically by using the Create Or Update Function Secret, Create Or Update Function Secret Slot, Create Or Update Host Secret and Create Or Update Host Secret Slot APIs.

    Function and host keys can be deleted programmatically by using the Delete Function Secret, Delete Function Secret Slot, Delete Host Secret, and Delete Host Secret Slot APIs.

    You can also use the legacy key management APIs to obtain function keys, but using the Azure Resource Manager APIs is recommended instead.

    API key authorization

    Most HTTP trigger templates require an API key in the request. So your HTTP request normally looks like the following URL:

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

    The key can be included in a query string variable named code, as above. It can also be included in an x-functions-key HTTP header. The value of the key can be any function key defined for the function, or any host key.

    You can allow anonymous requests, which do not require keys. You can also require that the master key is used. You change the default authorization level by using the authLevel property in the binding JSON. For more information, see Trigger - configuration.

    When running functions locally, authorization is disabled regardless of the specified authorization level setting. After publishing to Azure, the authLevel setting in your trigger is enforced. Keys are still required when running locally in a container.

    Secure an HTTP endpoint in production

    To fully secure your function endpoints in production, you should consider implementing one of the following function app-level security options. When using one of these function app-level security methods, you should set the HTTP-triggered function authorization level to anonymous.

    Enable App Service Authentication/Authorization

    The App Service platform lets you use Azure Active Directory (AAD) and several third-party identity providers to authenticate clients. You can use this strategy to implement custom authorization rules for your functions, and you can work with user information from your function code. To learn more, see Authentication and authorization in Azure App Service and Working with client identities.

    Use Azure API Management (APIM) to authenticate requests

    APIM provides a variety of API security options for incoming requests. To learn more, see API Management authentication policies. With APIM in place, you can configure your function app to accept requests only from the IP address of your APIM instance. To learn more, see IP address restrictions.

    Deploy your function app in isolation

    Azure App Service Environment (ASE) provides a dedicated hosting environment in which to run your functions. ASE lets you configure a single front-end gateway that you can use to authenticate all incoming requests. For more information, see Configuring a Web Application Firewall (WAF) for App Service Environment.

    Webhooks

    Webhook mode is only available for version 1.x of the Functions runtime. This change was made to improve the performance of HTTP triggers in version 2.x and higher.

    In version 1.x, webhook templates provide additional validation for webhook payloads. In version 2.x and higher, the base HTTP trigger still works and is the recommended approach for webhooks.

    WebHook type

    The webHookType binding property indicates the type if webhook supported by the function, which also dictates the supported payload. The webhook type can be one of the following values:

    Type value Description genericJson A general-purpose webhook endpoint without logic for a specific provider. This setting restricts requests to only those using HTTP POST and with the application/json content type. github The function responds to GitHub webhooks. Don't use the authLevel property with GitHub webhooks. slack The function responds to Slack webhooks. Don't use the authLevel property with Slack webhooks.

    When setting the webHookType property, don't also set the methods property on the binding.

    GitHub webhooks

    To respond to GitHub webhooks, first create your function with an HTTP Trigger, and set the webHookType property to github. Then copy its URL and API key into the Add webhook page of your GitHub repository.

    Slack webhooks

    The Slack webhook generates a token for you instead of letting you specify it, so you must configure a function-specific key with the token from Slack. See Authorization keys.

    Webhooks and keys

    Webhook authorization is handled by the webhook receiver component, part of the HTTP trigger, and the mechanism varies based on the webhook type. Each mechanism does rely on a key. By default, the function key named "default" is used. To use a different key, configure the webhook provider to send the key name with the request in one of the following ways:

  • Query string: The provider passes the key name in the clientid query string parameter, such as https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>.
  • Request header: The provider passes the key name in the x-functions-clientid header.
  • Content types

    Passing binary and form data to a non-C# function requires that you use the appropriate content-type header. Supported content types include octet-stream for binary data and multipart types.

    Known issues

    In non-C# functions, requests sent with the content-type image/jpeg results in a string value passed to the function. In cases like these, you can manually convert the string value to a byte array to access the raw binary data.

    Limits

    The HTTP request length is limited to 100 MB (104,857,600 bytes), and the URL length is limited to 4 KB (4,096 bytes). These limits are specified by the httpRuntime element of the runtime's Web.config file.

    If a function that uses the HTTP trigger doesn't complete within 230 seconds, the Azure Load Balancer will time out and return an HTTP 502 error. The function will continue running but will be unable to return an HTTP response. For long-running functions, we recommend that you follow async patterns and return a location where you can ping the status of the request. For information about how long a function can run, see Scale and hosting - Consumption plan.

    Next steps

  • Return an HTTP response from a function
  •