In ASP.NET Core how do you check if request is local?
In the regular ASP.NET you could do this in a view to determine if the current request was from localhost:
HttpContext.Current.Request.IsLocal
But I can't find something similar in ASP.NET 6/Core/whatever it is meant to be called.
UPDATE: ASP.NET Core 2.0 has a method called Url.IsLocalUrl
(see this Microsoft Docs).
I think this code will work, but I haven't been able to test it completely
var callingUrl = Request.Headers["Referer"].ToString();
var isLocal = Url.IsLocalUrl(callingUrl);
But see Will Dean's comment below about this approach:
Anyone thinking about using the 'updated' version which checks the Referrer header should bear in mind that headers are extremely easy to spoof, to a degree that doesn't apply to loopback IP addresses.
Original solution
I came across this looking for a solution to knowing if a request is local. Unfortunately ASP.NET version 1.1.0 does not have a IsLocal
method on a connection. I found one solution on a web site called Strathweb but that is out of date too.
I have created my own IsLocal
extension, and it seems to work, but I can't say I have tested it in all circumstances, but you are welcome to try it.
public static class IsLocalExtension
{
private const string NullIpAddress = "::1";
public static bool IsLocal(this HttpRequest req)
{
var connection = req.HttpContext.Connection;
if (connection.RemoteIpAddress.IsSet())
{
//We have a remote address set up
return connection.LocalIpAddress.IsSet()
//Is local is same as remote, then we are local
? connection.RemoteIpAddress.Equals(connection.LocalIpAddress)
//else we are remote if the remote IP address is not a loopback address
: IPAddress.IsLoopback(connection.RemoteIpAddress);
}
return true;
}
private static bool IsSet(this IPAddress address)
{
return address != null && address.ToString() != NullIpAddress;
}
}
You call it in a controller action from using the Request
property, i.e.
public IActionResult YourAction()
{
var isLocal = Request.IsLocal();
//... your code here
}
I hope that helps someone.
At the time of writing HttpContext.Connection.IsLocal
is now missing from .NET Core.
Other working solution checks only for a first loopback address (::1
or 127.0.0.1
) which might not be adequate.
I find the solution below useful:
using Microsoft.AspNetCore.Http;
using System.Net;
namespace ApiHelpers.Filters
{
public static class HttpContextFilters
{
public static bool IsLocalRequest(HttpContext context)
{
if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))
{
return true;
}
if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))
{
return true;
}
return false;
}
}
}
And the example use case:
app.UseWhen(HttpContextFilters.IsLocalRequest, configuration => configuration.UseElmPage());
None of the above worked for me.
Url.IsLocalUrl works very different and I find it a bit useless:
For example, the following URLs are considered local:
/Views/Default/Index.html
~/Index.html
The following URLs are non-local:
../Index.html
http://www.contoso.com/
http://localhost/Index.html
HttpContext.Connection.IsLocal
doesn't exist in .Net Core 2.2
Comparing ControllerContext.HttpContext.Connection.RemoteIpAddress
and ControllerContext.HttpContext.Connection.LocalIpAddress
also doesn't work in my test because I get "::1" for remote ip and "127.0.0.1" for local ip.
Finally, I used this piece:
IPAddress addr = System.Net.IPAddress.Parse( HttpContext.Connection.RemoteIpAddress.ToString() );
if (System.Net.IPAddress.IsLoopback(addr) )
{
//do something
}