从另一个调用一个 azure 函数时出现 403(禁止访问)

403 (Forbidden) while calling one azure function from another

我需要调用一个 azure 函数; fn(b),来自另一个 azure 函数; fn(a).

fn(a) -> fn(b)

这两个函数都在同一个函数应用程序中。问题是每当我尝试调用 (b) 时,我都会收到 403-Forbidden "data at the root level is invalid".

是否可以从同一函数应用程序中的另一个 azure 函数调用 azure 函数?

函数 1

public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]
            HttpRequestMessage req, TraceWriter log)
        {
            log.Info("---- C# HTTP trigger function 1 processed a request.");

            UploadToF2(log);
            return null;
        }

        private static IRestResponse UploadToF2(TraceWriter log)
        {
            SomeObject payload = new SomeObject();
            payload.One = "One";
            payload.Two = 2;
            payload.Three = false;
            payload.Four = 4.4;

            var Fn2Url = Convert.ToString(ConfigurationManager.AppSettings["F2Url"]);
            log.Info("Hitting F2 at " + Fn2Url);
            var method = Method.POST;
            var client = new RestClient(Fn2Url);
            var body = JsonConvert.SerializeObject(payload);

            var request = new RestRequest(method);
            request.RequestFormat = DataFormat.Json;
            request.AddHeader("Content-Type", "application/json");

            request.AddBody(payload); // uses JsonSerializer

            IRestResponse response = client.Execute(request);
            return response;
        }
    }

    class SomeObject
    {
        public string One { get; set; }
        public int Two { get; set; }
        public bool Three { get; set; }
        public double Four { get; set; }
    }

函数 2

public static class Function2
    {
        [FunctionName("Function2")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            log.Info("---- C# HTTP trigger function 2 processed a request.");
            string payload = await req.Content.ReadAsStringAsync();
            log.Info("payload == "+payload);

            return null;
        }
    }

附加信息:

  1. F2Url 是来自配置的完全限定 url。
  2. 我在 localhost 中尝试了 运行 这两个功能。有用。 IE。 fn(a) 可以在本地调用 fn(b)。但是,当我在 Azure 中托管它们时,无法从 fn(a) 调用 fn(b)。
  3. 我也试过混合测试。 IE。我在本地保留了一个功能,在 Azure 中保留了另一个功能。它也是这样工作的。 IE。我将 fn(a) 保存在本地,将 fn(b) 保存在 Azure 中,fn(b) 是可调用的。
  4. 我尝试直接从 Postman 调用 fn(b) 并且再次成功。
  5. authLevel 两个函数都是匿名的
  6. 我对函数应用应用了 IP 限制(平台功能 > 网络 > IP 限制)。当我取消 IP 限制时,Function1 可以调用 Function2。但是保持IP限制,不允许调用。

fn(a) 无法调用 fn(b) 的唯一条件是这两个函数都托管在 Azure 中。

在使用时通过 GET 到 Function1 在本地工作:

var Fn2Url = "http://localhost:7071/api/Function2";

您在配置中使用什么值?

  1. 完整调用函数 #2 URL,因为在请求到达您的函数应用程序之前,前端层会先被命中。即使对于在同一个函数应用程序中相互调用的函数也是如此。

    GET https://{func-app-name}.azurewebsites.net/api/function2
    
  2. 如果 authLevelfunction.json 中不是匿名的,则将 API 密钥作为 ?code=

    传递
    https://{func-app-name}.azurewebsites.net/api/function2?code={API-key}
    

    或作为 header —

    GET https://{func-app-name}.azurewebsites.net/api/function2
    x-functions-key: {API-key}
    

在本地运行时(Visual Studio/func host start),忽略authLevel的值。查看您的装饰器,AuthorizationLevel.Anonymous 存在,所以很可能不是它。

更多关于 authorization keys here

最重要的是,您可以在函数 #2 中返回 null 做得更好:200 OK202 Accepted204 No Content,所有有效的选择取决于什么接下来应该发生(async/sync 处理)。

403 (Forbidden) while calling one azure function from another

如果不在IP限制中添加客户端IP,那你在客户端测试会报403错误。如果不在IP限制中添加客户端IP,不仅可以从另一个调用azure功能,而且所有功能都将受到限制。

在你的情况下,你需要在IP限制中添加你的测试client Ip,然后它才会起作用。

更新:

添加测试结果。