【问题标题】:How to access server variables in ASP.Net Core 2.x如何在 ASP.Net Core 2.x 中访问服务器变量
【发布时间】:2018-07-18 06:00:56
【问题描述】:

我正在使用 ASP.Net core 2.0 Web 应用程序,它部署在 Azure 上。我需要做的是获取客户端 IP 地址。为此,我在整个互联网上搜索,发现服务器变量对我有帮助。

所以我从here 找到了这段代码来获取客户端 IP:

string IpAddress = this.Request.ServerVariables["REMOTE_ADDR"];

但是当我尝试上面的代码时,它显示一个错误“HttpRequest 不包含服务器变量的定义”

我也在尝试这个代码:

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

代码定义

RemoteIpAddress 发出请求的客户端的 IP 地址。请注意,这可能是针对代理而不是最终用户。

上面的代码正在获取 IP 地址,但它不是客户端 IP,每次我通过控制器访问上面的代码时,它都会刷新 IP。也许这是一个 Azure Web 服务代理,它每次都发出 get 请求。

在 ASP.Net Core 2.x 中访问服务器变量的正确方法是什么?

【问题讨论】:

  • 你试过request.HttpContext.Connection.RemoteIpAddress吗?
  • 另见Forwarded headers中间件。
  • @MukeshModhvadiya 是的,我已经尝试过,但当时它返回 null 但在 Mark G 评论中给出了简短解释后,我更改了中间件,所以现在我正在访问 IP 地址。我也发布了我的答案看看。
  • @MukeshModhvadiya 感谢您的宝贵时间和评论。

标签: c# asp.net asp.net-core


【解决方案1】:

我发现 Mark G 的参考链接非常有用。

我已经用ForwardedHeadersOptions 配置中间件来转发Startup.ConfigureServices 中的X-Forwarded-For 和X-Forwarded-Proto 标头。

这是我的 Startup.cs 代码文件:

配置服务

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
           options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

    services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddAspNetIdentity<ApplicationUser>();

    services.AddCors(options =>
    {
        options.AddPolicy("AllowClient",
                   builder => builder.WithOrigins("http://**.asyncsol.com", "http://*.asyncsol.com", "http://localhost:10761", "https://localhost:44335")
                                  .AllowAnyHeader()
                                  .AllowAnyMethod());
    });

    services.AddMvc();
    /* The relevant part for Forwarded Headers */
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    });

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        // base-address of your identityserver
        //options.Authority = "http://server.asyncsol.com/";
        options.Authority = "http://localhost:52718/";

        // name of the API resource
        options.Audience = "api1";

        options.RequireHttpsMetadata = false;
    });
}

配置

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    /* The relevant part for Forwarded Headers */
    app.UseForwardedHeaders();
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseIdentityServer();
    app.UseAuthentication();
    app.UseCors("AllowAll");
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "areas",
            template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
        );
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

在控制器上的使用

public IEnumerable<string> Get()
{
    string ip = Response.HttpContext.Connection.RemoteIpAddress.ToString();

    //https://en.wikipedia.org/wiki/Localhost
    //127.0.0.1    localhost
    //::1          localhost
    if (ip == "::1")
    {
        ip = Dns.GetHostEntry(Dns.GetHostName()).AddressList[2].ToString();
    }

    return new string[] { ip.ToString() };
}

所以,如果我在本地主机环境中运行,它会显示我的 IPv4 系统 IP 地址。
如果我在 azure 上运行我的服务器,它会显示我的主机名/IP 地址。

结论:

我在 Mark G 评论 Forwarded Headers Middleware 中找到了我的答案

【讨论】:

    【解决方案2】:

    【讨论】:

    • 我已经从您的参考资料中尝试了一些代码。就像,如果我想通过 dns 知道我的服务器 IP 地址,我已经使用了此代码 IPHostEntry heserver = Dns.GetHostEntry(Dns.GetHostName()); var ip = heserver.AddressList[2].ToString(); 我并不清楚此代码返回客户端或服务器 IP 但是当我在 azure 上部署我的 Web 应用程序时,我的应用程序会在这行代码中显示500 内部错误。如果我删除这行代码,我的网络应用程序运行良好。我认为 dns 不再适用于 azure。同时,如果我运行我的问题代码,每次我向它提出请求时,它都会向我显示新的 ip。
    • 希望你能理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多