0

What is the correct way of obtaining the remote IP address (the address of the client making the request) in an Azure durable function?

The beginning of my HttpStart method

        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "report-data/get")]
            HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient starter, ILogger log)
        {

I tried ((HttpContext)req.Properties["MS_HttpContext"]).Connection.RemoteIpAddress.ToString(); but the MS_HttpContext property is missing.

I also tried

        string result = string.Empty;

        if (req.Headers.TryGetValues("X-Forwarded-For", out IEnumerable<string> headerValues))
        {
            result = headerValues.FirstOrDefault();
        }
        return result;

which returns and empty string.

I have looked at this similar question, but it assumes the request is of type HttpRequest. In my case, it is HttpRequestMessage.

This answer suggests that the X-Forwarded-For header must be enabled first. But I don't know how to do this in my Azure Function App (or for my durable function).

I am developing my Azure functions locally, using VS Code.

ebhh2001
  • 2,034
  • 4
  • 18
  • 27

1 Answers1

0

After a bit of trying, I have managed to adapt this answer to my Azure Durable Function. I also found this information on how to use dependency injection in Azure functions quite handy. The steps were as follows:

  1. Add the following method to the project's Startup class in Startup.cs:
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        }
  1. Add the folowing using statement to Startup.cs: using Microsoft.AspNetCore.Http;
  2. Add the following private member and constructor to my orchestrator class
        private readonly IHttpContextAccessor _accessor;
        public GetReportActionsOrchestration(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }
  1. Add the following function for getting the client IP address to my orchestrator class:
        private string GetClientIpAddress()
        {
            string ip = _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
            return (string.IsNullOrWhiteSpace(ip)) ? string.Empty : ip;
        }

  1. Modify the durable orchestration code to be compatible with dependency injection by removing static modifier from the orchestration's HttpStart and RunOrchestrator functions.
  2. Add string remoteIpAddress = this.GetClientIpAddress(); to HttpStart function to get the client's IP address, which can then be passed to RunOrchestrator as a parameter.
  3. Changes to the orchestrator class require
        using Microsoft.AspNetCore.Http;
        using System;
ebhh2001
  • 2,034
  • 4
  • 18
  • 27