1
0

Changed behaviour of remote ip address detection, renamed ip allow/block lists

This commit is contained in:
2023-06-01 20:01:19 +02:00
parent d755754198
commit 371283e653
8 changed files with 135 additions and 77 deletions

View File

@@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters
/// <summary> /// <summary>
/// Implements an IP filter. Only defined addresses are allowed to access. /// Implements an IP filter. Only defined addresses are allowed to access.
/// </summary> /// </summary>
public class IPWhitelistAttribute : ActionFilterAttribute public class IPAllowListAttribute : ActionFilterAttribute
{ {
/// <summary> /// <summary>
/// Gets or sets a value indicating whether local (localhost) access is granted (Default: true). /// Gets or sets a value indicating whether local (localhost) access is granted (Default: true).

View File

@@ -10,12 +10,12 @@ namespace Microsoft.AspNetCore.Mvc.Filters
/// <summary> /// <summary>
/// Implements an IP filter. The defined addresses are blocked. /// Implements an IP filter. The defined addresses are blocked.
/// </summary> /// </summary>
public class IPBlacklistAttribute : ActionFilterAttribute public class IPBlockListAttribute : ActionFilterAttribute
{ {
/// <summary> /// <summary>
/// Gets or sets a value indicating whether local (localhost) access is blocked (Default: false). /// Gets or sets a value indicating whether local (localhost) access is blocked (Default: false).
/// </summary> /// </summary>
public bool RestrictLocalAccess { get; set; } public bool BlockLocalAccess { get; set; }
/// <summary> /// <summary>
/// Gets or sets a configuration key where the blocked IP addresses are defined. /// Gets or sets a configuration key where the blocked IP addresses are defined.
@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters
/// <summary> /// <summary>
/// Gets or sets a comma separated list of blocked IP addresses. /// Gets or sets a comma separated list of blocked IP addresses.
/// </summary> /// </summary>
public string RestrictedIpAddresses { get; set; } public string BlockedIpAddresses { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
public override void OnActionExecuting(ActionExecutingContext context) public override void OnActionExecuting(ActionExecutingContext context)
@@ -43,13 +43,13 @@ namespace Microsoft.AspNetCore.Mvc.Filters
base.OnActionExecuting(context); base.OnActionExecuting(context);
context.HttpContext.Items["RemoteAddress"] = context.HttpContext.GetRemoteIpAddress(); context.HttpContext.Items["RemoteAddress"] = context.HttpContext.GetRemoteIpAddress();
if (!RestrictLocalAccess && context.HttpContext.IsLocalRequest()) if (!BlockLocalAccess && context.HttpContext.IsLocalRequest())
return; return;
var remoteIpAddress = context.HttpContext.GetRemoteIpAddress(); var remoteIpAddress = context.HttpContext.GetRemoteIpAddress();
if (!string.IsNullOrWhiteSpace(RestrictedIpAddresses)) if (!string.IsNullOrWhiteSpace(BlockedIpAddresses))
{ {
string[] ipAddresses = RestrictedIpAddresses.Split(','); string[] ipAddresses = BlockedIpAddresses.Split(',');
foreach (string ipAddress in ipAddresses) foreach (string ipAddress in ipAddresses)
{ {
if (string.IsNullOrWhiteSpace(ipAddress)) if (string.IsNullOrWhiteSpace(ipAddress))

View File

@@ -1,4 +1,5 @@
using System.Net; using System.Linq;
using System.Net;
using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Antiforgery;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -9,30 +10,57 @@ namespace Microsoft.AspNetCore.Http
/// </summary> /// </summary>
public static class HttpContextExtensions public static class HttpContextExtensions
{ {
// Search these additional headers for a remote client ip address.
private static readonly string[] defaultIpHeaderNames = new[]
{
"X-Forwarded-For", // commonly used on all known proxies
"X-Real-IP", // wide-spread alternative to X-Forwarded-For
"CF-Connecting-IP" // set by Cloudflare
};
/// <summary> /// <summary>
/// Retrieves the antiforgery token. /// Retrieves the antiforgery token.
/// </summary> /// </summary>
/// <param name="httpContext">The current <see cref="HttpContext"/>.</param> /// <param name="httpContext">The current <see cref="HttpContext"/>.</param>
/// <returns>Name and value of the token.</returns> /// <returns>FormName, HeaderName and Value of the antiforgery token.</returns>
public static (string Name, string Value) GetAntiforgeryToken(this HttpContext httpContext) public static (string FormName, string HeaderName, string Value) GetAntiforgeryToken(this HttpContext httpContext)
{ {
var af = httpContext.RequestServices.GetService<IAntiforgery>(); var antiforgery = httpContext.RequestServices.GetService<IAntiforgery>();
var set = af?.GetAndStoreTokens(httpContext); var tokenSet = antiforgery?.GetAndStoreTokens(httpContext);
return (Name: set?.FormFieldName, Value: set?.RequestToken); return (tokenSet?.FormFieldName, tokenSet?.HeaderName, tokenSet?.RequestToken);
} }
/// <summary> /// <summary>
/// Returns the remote ip address. /// Returns the remote ip address.
/// </summary> /// </summary>
/// <remarks>
/// Searches for additional headers in the following order:
/// <list type="number">
/// <item>X-Forwarded-For</item>
/// <item>X-Real-IP</item>
/// <item>CF-Connecting-IP</item>
/// </list>
/// </remarks>
/// <param name="httpContext">The current <see cref="HttpContext"/>.</param> /// <param name="httpContext">The current <see cref="HttpContext"/>.</param>
/// <param name="headerName">The name of the header to resolve the <see cref="IPAddress"/> when behind a proxy (Default: X-Forwarded-For).</param> /// <param name="ipHeaderName">The name of the header to resolve the <see cref="IPAddress"/> when behind a proxy.</param>
/// <returns>The ip address of the client.</returns> /// <returns>The ip address of the client.</returns>
public static IPAddress GetRemoteIpAddress(this HttpContext httpContext, string headerName = "X-Forwarded-For") public static IPAddress GetRemoteIpAddress(this HttpContext httpContext, string ipHeaderName = null)
{ {
string forwardedHeader = httpContext.Request.Headers[headerName].ToString(); string forwardedForAddress = null;
if (!string.IsNullOrWhiteSpace(forwardedHeader) && IPAddress.TryParse(forwardedHeader, out var forwarded))
return forwarded; var headerNames = string.IsNullOrWhiteSpace(ipHeaderName) ? defaultIpHeaderNames : new[] { ipHeaderName }.Concat(defaultIpHeaderNames);
foreach (string headerName in headerNames)
{
if (!httpContext.Request.Headers.ContainsKey(headerName))
continue;
forwardedForAddress = httpContext.Request.Headers[headerName].ToString();
break;
}
if (!string.IsNullOrWhiteSpace(forwardedForAddress) && IPAddress.TryParse(forwardedForAddress, out var remoteAddress))
return remoteAddress;
return httpContext.Connection.RemoteIpAddress; return httpContext.Connection.RemoteIpAddress;
} }
@@ -40,12 +68,20 @@ namespace Microsoft.AspNetCore.Http
/// <summary> /// <summary>
/// Returns whether the request was made locally. /// Returns whether the request was made locally.
/// </summary> /// </summary>
/// <remarks>
/// Searches for additional headers in the following order:
/// <list type="number">
/// <item>X-Forwarded-For</item>
/// <item>X-Real-IP</item>
/// <item>CF-Connecting-IP</item>
/// </list>
/// </remarks>
/// <param name="httpContext">The current <see cref="HttpContext"/>.</param> /// <param name="httpContext">The current <see cref="HttpContext"/>.</param>
/// <param name="headerName">The name of the header to resolve the <see cref="IPAddress"/> when behind a proxy (Default: X-Forwarded-For).</param> /// <param name="ipHeaderName">The name of the header to resolve the <see cref="IPAddress"/> when behind a proxy.</param>
/// <returns></returns> /// <returns></returns>
public static bool IsLocalRequest(this HttpContext httpContext, string headerName = "X-Forwarded-For") public static bool IsLocalRequest(this HttpContext httpContext, string ipHeaderName = null)
{ {
var remoteIpAddress = httpContext.GetRemoteIpAddress(headerName); var remoteIpAddress = httpContext.GetRemoteIpAddress(ipHeaderName);
return httpContext.Connection.LocalIpAddress.Equals(remoteIpAddress); return httpContext.Connection.LocalIpAddress.Equals(remoteIpAddress);
} }

View File

@@ -5,11 +5,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Upcoming](https://git.am-wd.de/AM.WD/common/compare/v1.11.1...main) - 0000-00-00 ## [Upcoming](https://git.am-wd.de/AM.WD/common/compare/v1.12.0...main) - 0000-00-00
_no changes yet_ _no changes yet_
## [v1.12.0](https://git.am-wd.de/AM.WD/common/compare/v1.11.1...v1.12.0) - 2023-06-01
### Changed
- Renamed `IPBlacklistAttribute` to `IPBlockListAttribute`
- Renamed `IPWhitelistAttribute` to `IPAllowListAttribute`
- `HttpContextExtensions`
- `GetAntiforgeryToken()` now returns the header name also
- `GetRemoteIpAddress()` checks following additional headers by default:
- `X-Forwarded-For`
- `X-Real-IP`
- `CF-Connecting-IP`
## [v1.11.1](https://git.am-wd.de/AM.WD/common/compare/v1.11.0...v1.11.1) - 2023-05-11 ## [v1.11.1](https://git.am-wd.de/AM.WD/common/compare/v1.11.0...v1.11.1) - 2023-05-11
### Fixed ### Fixed

View File

@@ -6,8 +6,4 @@
<Copy SourceFiles="$(MSBuildProjectDirectory)\bin\$(Configuration)\$(PackageId).$(PackageVersion).nupkg" DestinationFolder="D:\NuGetLocal" /> <Copy SourceFiles="$(MSBuildProjectDirectory)\bin\$(Configuration)\$(PackageId).$(PackageVersion).nupkg" DestinationFolder="D:\NuGetLocal" />
<Copy SourceFiles="$(MSBuildProjectDirectory)\bin\$(Configuration)\$(PackageId).$(PackageVersion).snupkg" DestinationFolder="D:\NuGetLocal" /> <Copy SourceFiles="$(MSBuildProjectDirectory)\bin\$(Configuration)\$(PackageId).$(PackageVersion).snupkg" DestinationFolder="D:\NuGetLocal" />
</Target> </Target>
<Target Condition="'$(Configuration)' == 'DebugLocal'" Name="PushToLocalFeed" AfterTargets="Pack">
<Exec Command="dotnet nuget push -s https://nuget.syshorst.de/v3/index.json $(MSBuildProjectDirectory)\bin\$(Configuration)\$(PackageId).$(PackageVersion).nupkg" />
</Target>
</Project> </Project>

View File

@@ -14,7 +14,7 @@ namespace UnitTests.AspNetCore.Attributes
{ {
[TestClass] [TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class IPWhitelistAttributeTests public class IPAllowListAttributeTests
{ {
private Dictionary<string, string> requestHeaders; private Dictionary<string, string> requestHeaders;
private Dictionary<object, object> itemsCallback; private Dictionary<object, object> itemsCallback;
@@ -37,7 +37,7 @@ namespace UnitTests.AspNetCore.Attributes
{ {
// arrange // arrange
var remote = IPAddress.Parse("192.168.178.1"); var remote = IPAddress.Parse("192.168.178.1");
var attribute = new IPWhitelistAttribute(); var attribute = new IPAllowListAttribute();
var context = GetContext(remote); var context = GetContext(remote);
// act // act
@@ -57,7 +57,7 @@ namespace UnitTests.AspNetCore.Attributes
{ {
// arrange // arrange
var remote = IPAddress.Parse("192.168.178.1"); var remote = IPAddress.Parse("192.168.178.1");
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowedIpAddresses = "192.168.178:1" AllowedIpAddresses = "192.168.178:1"
}; };
@@ -79,7 +79,7 @@ namespace UnitTests.AspNetCore.Attributes
public void ShouldAllowLocalAccess() public void ShouldAllowLocalAccess()
{ {
// arrange // arrange
var attribute = new IPWhitelistAttribute(); var attribute = new IPAllowListAttribute();
var context = GetContext(); var context = GetContext();
// act // act
@@ -95,7 +95,7 @@ namespace UnitTests.AspNetCore.Attributes
public void ShouldDenyLocalAccess() public void ShouldDenyLocalAccess()
{ {
// arrange // arrange
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowLocalAccess = false AllowLocalAccess = false
}; };
@@ -120,7 +120,7 @@ namespace UnitTests.AspNetCore.Attributes
{ {
// arrange // arrange
var remote = IPAddress.Parse(address); var remote = IPAddress.Parse(address);
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowLocalAccess = false, AllowLocalAccess = false,
AllowedIpAddresses = ",127.0.0.0/8,192.168.178.10" AllowedIpAddresses = ",127.0.0.0/8,192.168.178.10"
@@ -154,7 +154,7 @@ namespace UnitTests.AspNetCore.Attributes
configExists = true; configExists = true;
allowedIpsConfig.Add("127.0.0.0/8"); allowedIpsConfig.Add("127.0.0.0/8");
allowedIpsConfig.Add("192.168.178.10"); allowedIpsConfig.Add("192.168.178.10");
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowLocalAccess = true, AllowLocalAccess = true,
ConfigurationKey = configKey ConfigurationKey = configKey
@@ -178,7 +178,7 @@ namespace UnitTests.AspNetCore.Attributes
configExists = true; configExists = true;
allowedIpsConfig.Add(""); allowedIpsConfig.Add("");
allowedIpsConfig.Add("192.168.178.10"); allowedIpsConfig.Add("192.168.178.10");
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowLocalAccess = false, AllowLocalAccess = false,
ConfigurationKey = configKey ConfigurationKey = configKey
@@ -206,7 +206,7 @@ namespace UnitTests.AspNetCore.Attributes
configKey = "White:List"; configKey = "White:List";
configExists = true; configExists = true;
allowedIpsConfig.Add("192.168.178.10"); allowedIpsConfig.Add("192.168.178.10");
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowLocalAccess = false, AllowLocalAccess = false,
ConfigurationKey = configKey ConfigurationKey = configKey
@@ -239,7 +239,7 @@ namespace UnitTests.AspNetCore.Attributes
// arrange // arrange
configKey = "White:List"; configKey = "White:List";
configExists = false; configExists = false;
var attribute = new IPWhitelistAttribute var attribute = new IPAllowListAttribute
{ {
AllowLocalAccess = false, AllowLocalAccess = false,
ConfigurationKey = configKey ConfigurationKey = configKey

View File

@@ -14,7 +14,7 @@ namespace UnitTests.AspNetCore.Attributes
{ {
[TestClass] [TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class IPBlacklistAttributeTests public class IPBlockListAttributeTests
{ {
private Dictionary<string, string> requestHeaders; private Dictionary<string, string> requestHeaders;
private Dictionary<object, object> itemsCallback; private Dictionary<object, object> itemsCallback;
@@ -37,7 +37,7 @@ namespace UnitTests.AspNetCore.Attributes
{ {
// arrange // arrange
var remote = IPAddress.Parse("192.168.178.1"); var remote = IPAddress.Parse("192.168.178.1");
var attribute = new IPBlacklistAttribute(); var attribute = new IPBlockListAttribute();
var context = GetContext(remote); var context = GetContext(remote);
// act // act
@@ -54,9 +54,9 @@ namespace UnitTests.AspNetCore.Attributes
{ {
// arrange // arrange
var remote = IPAddress.Parse("192.168.178.1"); var remote = IPAddress.Parse("192.168.178.1");
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictedIpAddresses = "192.168.178:1" BlockedIpAddresses = "192.168.178:1"
}; };
var context = GetContext(remote); var context = GetContext(remote);
@@ -73,10 +73,10 @@ namespace UnitTests.AspNetCore.Attributes
public void ShouldAllowLocalAccess() public void ShouldAllowLocalAccess()
{ {
// arrange // arrange
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = false, BlockLocalAccess = false,
RestrictedIpAddresses = "127.0.0.0/8" BlockedIpAddresses = "127.0.0.0/8"
}; };
var context = GetContext(); var context = GetContext();
@@ -93,10 +93,10 @@ namespace UnitTests.AspNetCore.Attributes
public void ShouldBlockLocalAccess() public void ShouldBlockLocalAccess()
{ {
// arrange // arrange
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = true, BlockLocalAccess = true,
RestrictedIpAddresses = ",127.0.0.0/8" BlockedIpAddresses = ",127.0.0.0/8"
}; };
var context = GetContext(); var context = GetContext();
@@ -119,10 +119,10 @@ namespace UnitTests.AspNetCore.Attributes
{ {
// arrange // arrange
var remote = IPAddress.Parse(address); var remote = IPAddress.Parse(address);
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = true, BlockLocalAccess = true,
RestrictedIpAddresses = "127.0.0.0/8,192.168.178.10" BlockedIpAddresses = "127.0.0.0/8,192.168.178.10"
}; };
var context = GetContext(remote); var context = GetContext(remote);
@@ -153,9 +153,9 @@ namespace UnitTests.AspNetCore.Attributes
configExists = true; configExists = true;
restrictedIpsConfig.Add("127.0.0.0/8"); restrictedIpsConfig.Add("127.0.0.0/8");
restrictedIpsConfig.Add("192.168.178.10"); restrictedIpsConfig.Add("192.168.178.10");
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = false, BlockLocalAccess = false,
ConfigurationKey = configKey ConfigurationKey = configKey
}; };
var context = GetContext(); var context = GetContext();
@@ -178,9 +178,9 @@ namespace UnitTests.AspNetCore.Attributes
restrictedIpsConfig.Add(""); restrictedIpsConfig.Add("");
restrictedIpsConfig.Add("127.0.0.0/8"); restrictedIpsConfig.Add("127.0.0.0/8");
restrictedIpsConfig.Add("192.168.178.10"); restrictedIpsConfig.Add("192.168.178.10");
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = true, BlockLocalAccess = true,
ConfigurationKey = configKey ConfigurationKey = configKey
}; };
var context = GetContext(); var context = GetContext();
@@ -207,9 +207,9 @@ namespace UnitTests.AspNetCore.Attributes
configExists = true; configExists = true;
restrictedIpsConfig.Add("127.0.0.0/8"); restrictedIpsConfig.Add("127.0.0.0/8");
restrictedIpsConfig.Add("192.168.178.10"); restrictedIpsConfig.Add("192.168.178.10");
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = true, BlockLocalAccess = true,
ConfigurationKey = configKey ConfigurationKey = configKey
}; };
var remote = IPAddress.Parse(address); var remote = IPAddress.Parse(address);
@@ -240,9 +240,9 @@ namespace UnitTests.AspNetCore.Attributes
// arrange // arrange
configKey = "Black:List"; configKey = "Black:List";
configExists = false; configExists = false;
var attribute = new IPBlacklistAttribute var attribute = new IPBlockListAttribute
{ {
RestrictLocalAccess = true, BlockLocalAccess = true,
ConfigurationKey = configKey ConfigurationKey = configKey
}; };
var context = GetContext(); var context = GetContext();

View File

@@ -14,7 +14,8 @@ namespace UnitTests.AspNetCore.Extensions
{ {
private Mock<ISession> sessionMock; private Mock<ISession> sessionMock;
private string tokenName; private string tokenFormName;
private string tokenHeaderName;
private string tokenValue; private string tokenValue;
private Dictionary<string, string> requestHeaders; private Dictionary<string, string> requestHeaders;
@@ -26,7 +27,8 @@ namespace UnitTests.AspNetCore.Extensions
[TestInitialize] [TestInitialize]
public void InitializeTests() public void InitializeTests()
{ {
tokenName = null; tokenFormName = null;
tokenHeaderName = null;
tokenValue = null; tokenValue = null;
requestHeaders = new Dictionary<string, string>(); requestHeaders = new Dictionary<string, string>();
@@ -42,34 +44,38 @@ namespace UnitTests.AspNetCore.Extensions
public void ShouldReturnAntiforgery() public void ShouldReturnAntiforgery()
{ {
// arrange // arrange
tokenName = "af-token"; tokenFormName = "af-token";
tokenHeaderName = "af-header";
tokenValue = "security_first"; tokenValue = "security_first";
var context = GetContext(); var context = GetContext();
// act // act
var result = context.GetAntiforgeryToken(); var (formName, headerName, value) = context.GetAntiforgeryToken();
// assert // assert
Assert.AreEqual(tokenName, result.Name); Assert.AreEqual(tokenFormName, formName);
Assert.AreEqual(tokenValue, result.Value); Assert.AreEqual(tokenHeaderName, headerName);
Assert.AreEqual(tokenValue, value);
} }
[TestMethod] [TestMethod]
public void ShouldReturnAntiforgeryNullService() public void ShouldReturnAntiforgeryNullService()
{ {
// arrange // arrange
tokenName = "af-token"; tokenFormName = "af-token";
tokenHeaderName = "af-header";
tokenValue = "security_first"; tokenValue = "security_first";
var context = GetContext(hasAntiforgery: false); var context = GetContext(hasAntiforgery: false);
// act // act
var result = context.GetAntiforgeryToken(); var (formName, headerName, value) = context.GetAntiforgeryToken();
// assert // assert
Assert.AreEqual(null, result.Name); Assert.IsNull(formName);
Assert.AreEqual(null, result.Value); Assert.IsNull(headerName);
Assert.IsNull(value);
} }
[TestMethod] [TestMethod]
@@ -79,11 +85,12 @@ namespace UnitTests.AspNetCore.Extensions
var context = GetContext(); var context = GetContext();
// act // act
var result = context.GetAntiforgeryToken(); var (formName, headerName, value) = context.GetAntiforgeryToken();
// assert // assert
Assert.AreEqual(null, result.Name); Assert.IsNull(formName);
Assert.AreEqual(null, result.Value); Assert.IsNull(headerName);
Assert.IsNull(value);
} }
#endregion Antiforgery #endregion Antiforgery
@@ -105,13 +112,16 @@ namespace UnitTests.AspNetCore.Extensions
Assert.AreEqual(remote, result); Assert.AreEqual(remote, result);
} }
[TestMethod] [DataTestMethod]
public void ShouldReturnDefaultHeader() [DataRow("X-Forwarded-For")]
[DataRow("X-Real-IP")]
[DataRow("CF-Connecting-IP")]
public void ShouldReturnDefaultHeader(string headerName)
{ {
// arrange // arrange
remote = IPAddress.Parse("1.2.3.4"); remote = IPAddress.Parse("1.2.3.4");
var header = IPAddress.Parse("5.6.7.8"); var header = IPAddress.Parse("5.6.7.8");
requestHeaders.Add("X-Forwarded-For", header.ToString()); requestHeaders.Add(headerName, header.ToString());
var context = GetContext(); var context = GetContext();
@@ -130,12 +140,14 @@ namespace UnitTests.AspNetCore.Extensions
remote = IPAddress.Parse("1.2.3.4"); remote = IPAddress.Parse("1.2.3.4");
string headerName = "FooBar"; string headerName = "FooBar";
var headerIp = IPAddress.Parse("5.6.7.8"); var headerIp = IPAddress.Parse("5.6.7.8");
requestHeaders.Add(headerName, headerIp.ToString()); requestHeaders.Add(headerName, headerIp.ToString());
requestHeaders.Add("X-Forwarded-For", remote.ToString());
var context = GetContext(); var context = GetContext();
// act // act
var result = context.GetRemoteIpAddress(headerName: headerName); var result = context.GetRemoteIpAddress(ipHeaderName: headerName);
// assert // assert
Assert.AreNotEqual(remote, result); Assert.AreNotEqual(remote, result);
@@ -221,7 +233,7 @@ namespace UnitTests.AspNetCore.Extensions
var context = GetContext(); var context = GetContext();
// act // act
bool result = context.IsLocalRequest(headerName: headerName); bool result = context.IsLocalRequest(ipHeaderName: headerName);
// assert // assert
Assert.IsTrue(result); Assert.IsTrue(result);
@@ -254,7 +266,7 @@ namespace UnitTests.AspNetCore.Extensions
var context = GetContext(); var context = GetContext();
// act // act
bool result = context.IsLocalRequest(headerName: headerName); bool result = context.IsLocalRequest(ipHeaderName: headerName);
// assert // assert
Assert.IsFalse(result); Assert.IsFalse(result);
@@ -385,7 +397,7 @@ namespace UnitTests.AspNetCore.Extensions
var antiforgeryMock = new Mock<IAntiforgery>(); var antiforgeryMock = new Mock<IAntiforgery>();
antiforgeryMock antiforgeryMock
.Setup(af => af.GetAndStoreTokens(It.IsAny<HttpContext>())) .Setup(af => af.GetAndStoreTokens(It.IsAny<HttpContext>()))
.Returns(string.IsNullOrWhiteSpace(tokenName) ? null : new AntiforgeryTokenSet(tokenValue, tokenValue, tokenName, tokenName)); .Returns(() => string.IsNullOrWhiteSpace(tokenValue) ? null : new AntiforgeryTokenSet(tokenValue, tokenValue, tokenFormName, tokenHeaderName));
requestServicesMock requestServicesMock
.Setup(rs => rs.GetService(typeof(IAntiforgery))) .Setup(rs => rs.GetService(typeof(IAntiforgery)))