Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access server variables in ASP.Net Core 2.x

I m using ASP.Net core 2.0 web app and it is deployed on Azure. What I need to do is to get client IP Address. For this, I m searching all over the internet and found that the server variables help me on this.

So I found this code from here to get Client IP using:

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

But when I'm trying above code it shows me an error "HttpRequest does not contain a definition for Server Variables"

Also I was try this code:

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

Code Definition

RemoteIpAddress The IP Address of the client making the request. Note this may be for a proxy rather than the end user.

Above code is getting the IP address but it is not a clientip and each time when I access above code via controller it refreshes the IP. Maybe this is an Azure web service proxy which makes get request each time.

What is the right way to access server variables in ASP.Net Core 2.x?

like image 300
Ahmer Ali Ahsan Avatar asked Jul 18 '18 06:07

Ahmer Ali Ahsan


People also ask

What are server variables in ASP core?

In Asp.Net Core, you can view a list of data known as Server Variables. These are available when hosting inside IIS, and they give information about the request call and security. You can view any one of these by adding some middleware to your Asp.Net Core project:

What is web server in ASP NET Core?

Web server implementations in ASP.NET Core. An ASP.NET Core app runs with an in-process HTTP server implementation. The server implementation listens for HTTP requests and surfaces them to the app as a set of request features composed into an HttpContext.

What are server variables in IIS?

In Asp.Net Core, you can view a list of data known as Server Variables. These are available when hosting inside IIS, and they give information about the request call and security.

What is ASP NET Core Module in IIS?

The ASP.NET Core Module is a native IIS module that handles native IIS requests between IIS and the in-process IIS HTTP Server or Kestrel. For more information, see ASP.NET Core Module (ANCM) for IIS.


1 Answers

I've found Mark G's reference link very useful.

I've configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices.

Here is my Startup.cs code file:

ConfigureServices

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

Configure

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?}");
    });
}

Usage at a Controller

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

So, If I'm running on my localhost environment it shows my IPv4 system IP Address.
If I'm running my server on azure it shows my Host Name / IP Address.

Conclusion:

I've found my answer in Mark G comment Forwarded Headers Middleware

like image 191
Ahmer Ali Ahsan Avatar answered Sep 18 '22 05:09

Ahmer Ali Ahsan