c# - 使用 HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress 时获取 127.0.0.1

标签 c# azure asp.net-core asp.net-core-mvc

我正在使用 asp.net core 和 mvc。我正在尝试使用以下代码获取 IP 地址。

var ipAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress?.ToString();

它总是返回::1,这意味着我的本地计算机上的 127.0.0.1 没问题。但现在我已将其托管在 azure 云上,仅用于使用我的测试 azure 帐户进行测试,并且它仍然为我提供 127.0.0.1。

我做错了什么?

project.json

    {
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0-rc2-3002702",
      "author": [ "Musaab Mushtaq", "Programmer" ],
      "type": "platform"
    },
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
    "Microsoft.AspNetCore.Mvc.ViewFeatures": "1.0.0-rc2-final",
    "DeveloperForce.Force": "1.3.0",
    "Microsoft.Framework.Configuration": "1.0.0-beta8",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc2-final",
    "IntegraPay.Domain": "1.0.0-*"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    }
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "dnxcore50",
        "portable-net45+win8",
        "net45"
      ],
      "dependencies": {
      }
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "gcServer": true
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "web.config",
      "config.json",
      "Views"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Startup.cs

  public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<ForwardedHeadersOptions>(option => { option.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForward‌​edFor; });
            services.AddMvc();
            services.AddSingleton(provider => Configuration);
            services.AddTransient<IRegistrationRepository, ServiceUtilities>();
            services.AddTransient<IClientServiceConnector, ClientServiceValidation>();
        }

        private IClientServiceConnector ForceClientService { get;set; }
        private IConfiguration Configuration { get; set; }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment enviroment)
        {
            app.UseStaticFiles();
            if (enviroment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Registration/Error");
            }

            app.UseRuntimeInfoPage("/Info");
            app.UseFileServer();
            ConfigureRestAuthenticationSetting(enviroment);
            app.UseMvc(ConfigureRoutes);
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

        private void ConfigureRestAuthenticationSetting(IHostingEnvironment enviroment)
        {
            var config = new ConfigurationBuilder()
                .SetBasePath(enviroment.ContentRootPath)
                .AddJsonFile("config.json");
            Configuration = config.Build();
        }

        private void ConfigureRoutes(IRouteBuilder routeBuilder)
        {
            routeBuilder.MapRoute("Default", "{controller=Registration}/{action=Index}/{formId?}");
        }


    }

最佳答案

发生这种情况是因为反向代理。使用 ASP.net core IIS 将请求发送到 Kestrel 服务器进行处理,并在 MVC 6(ASP.net core)接收请求后出现此问题,因为某些 header 信息将不会被转发。

以下内容将解决您的问题。

在您的 Startup.cs 文件中。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
      loggerFactory.AddConsole(Configuration.GetSection("Logging"));
      loggerFactory.AddDebug();
      app.UseForwardedHeaders(new ForwardedHeadersOptions() { ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All }); // This must be first line. ( Before other middleware get configured)
      // your other code
    }

更新 1 1.不要同时使用Service.Configure和app.UseForwardedHeaders。 (我尝试同时使用这两个选项,最终结果为 127.0.0.1)。 2.我只使用了app.UseForwardedHeaders并且工作正常。

我的最小配置文件。 (启动.cs)

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddMvc();
        //services.Configure<ForwardedHeadersOptions>(option => { option.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All; });  // This option should not be used. it gives me 127.0.0.1 if I have used this option.
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(LogLevel.Debug);
        app.UseForwardedHeaders(new ForwardedHeadersOptions() { ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All });
        app.UseStaticFiles();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }
}

更新2

后来我尝试使用 Service.Configure 并且它有效。在这种情况下,我只使用 Service.Configure 并避免使用 app.UseForwardedHeaders。

在这种情况下,我的 Startup.cs 文件如下所示。

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddMvc();
        services.Configure<ForwardedHeadersOptions>(option => { option.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForward‌​edFor; });  
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(LogLevel.Debug);
        //app.UseForwardedHeaders(new ForwardedHeadersOptions() { ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All });
        app.UseStaticFiles();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }
}

关于c# - 使用 HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress 时获取 127.0.0.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39113100/

相关文章:

php - 连接字符串错误,PHP 与 Azure 中部署的 MySQL

Python SDK Azure 资源图响应不可迭代

asp.net-core - 任务失败 : Activating language client: HtmlLanguageClient

asp.net-core - ASP.NET 核心 2.0 InvalidOperationException : Cannot find compilation library location for package '<assemblyname>'

c# - 当我没有实例化 "Response.Redirect"时,如何从 Razor 网页使用 "Response"?

c# - 从 HashTable 键创建一个 List<string>?

c# - 通过 HTTPClient 使用 c# CLR 存储过程调用 Web API 2 方法

将数据提取为 XML 格式的 Azure 作业

c# - 如何使用 MS.DI 和 .NET Core 从静态方法重构为依赖注入(inject)?

c# - System.Text.Json.Serialization 替换 Netwtonsoft 的 JsonObjectAttribute NamingStrategy 设置