diff --git a/AMWD.Common.AspNetCore/Attributes/IPWhitelistAttribute.cs b/AMWD.Common.AspNetCore/Attributes/IPAllowListAttribute.cs
similarity index 94%
rename from AMWD.Common.AspNetCore/Attributes/IPWhitelistAttribute.cs
rename to AMWD.Common.AspNetCore/Attributes/IPAllowListAttribute.cs
index ef2f9bb..4441633 100644
--- a/AMWD.Common.AspNetCore/Attributes/IPWhitelistAttribute.cs
+++ b/AMWD.Common.AspNetCore/Attributes/IPAllowListAttribute.cs
@@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters
///
/// Implements an IP filter. Only defined addresses are allowed to access.
///
- public class IPWhitelistAttribute : ActionFilterAttribute
+ public class IPAllowListAttribute : ActionFilterAttribute
{
///
/// Gets or sets a value indicating whether local (localhost) access is granted (Default: true).
diff --git a/AMWD.Common.AspNetCore/Attributes/IPBlacklistAttribute.cs b/AMWD.Common.AspNetCore/Attributes/IPBlockListAttribute.cs
similarity index 85%
rename from AMWD.Common.AspNetCore/Attributes/IPBlacklistAttribute.cs
rename to AMWD.Common.AspNetCore/Attributes/IPBlockListAttribute.cs
index 9ca9c88..36d3e33 100644
--- a/AMWD.Common.AspNetCore/Attributes/IPBlacklistAttribute.cs
+++ b/AMWD.Common.AspNetCore/Attributes/IPBlockListAttribute.cs
@@ -10,12 +10,12 @@ namespace Microsoft.AspNetCore.Mvc.Filters
///
/// Implements an IP filter. The defined addresses are blocked.
///
- public class IPBlacklistAttribute : ActionFilterAttribute
+ public class IPBlockListAttribute : ActionFilterAttribute
{
///
/// Gets or sets a value indicating whether local (localhost) access is blocked (Default: false).
///
- public bool RestrictLocalAccess { get; set; }
+ public bool BlockLocalAccess { get; set; }
///
/// Gets or sets a configuration key where the blocked IP addresses are defined.
@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters
///
/// Gets or sets a comma separated list of blocked IP addresses.
///
- public string RestrictedIpAddresses { get; set; }
+ public string BlockedIpAddresses { get; set; }
///
public override void OnActionExecuting(ActionExecutingContext context)
@@ -43,13 +43,13 @@ namespace Microsoft.AspNetCore.Mvc.Filters
base.OnActionExecuting(context);
context.HttpContext.Items["RemoteAddress"] = context.HttpContext.GetRemoteIpAddress();
- if (!RestrictLocalAccess && context.HttpContext.IsLocalRequest())
+ if (!BlockLocalAccess && context.HttpContext.IsLocalRequest())
return;
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)
{
if (string.IsNullOrWhiteSpace(ipAddress))
diff --git a/AMWD.Common.AspNetCore/Extensions/HttpContextExtensions.cs b/AMWD.Common.AspNetCore/Extensions/HttpContextExtensions.cs
index d630d61..13f49c3 100644
--- a/AMWD.Common.AspNetCore/Extensions/HttpContextExtensions.cs
+++ b/AMWD.Common.AspNetCore/Extensions/HttpContextExtensions.cs
@@ -1,4 +1,5 @@
-using System.Net;
+using System.Linq;
+using System.Net;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.Extensions.DependencyInjection;
@@ -9,30 +10,57 @@ namespace Microsoft.AspNetCore.Http
///
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
+ };
+
///
/// Retrieves the antiforgery token.
///
/// The current .
- /// Name and value of the token.
- public static (string Name, string Value) GetAntiforgeryToken(this HttpContext httpContext)
+ /// FormName, HeaderName and Value of the antiforgery token.
+ public static (string FormName, string HeaderName, string Value) GetAntiforgeryToken(this HttpContext httpContext)
{
- var af = httpContext.RequestServices.GetService();
- var set = af?.GetAndStoreTokens(httpContext);
+ var antiforgery = httpContext.RequestServices.GetService();
+ var tokenSet = antiforgery?.GetAndStoreTokens(httpContext);
- return (Name: set?.FormFieldName, Value: set?.RequestToken);
+ return (tokenSet?.FormFieldName, tokenSet?.HeaderName, tokenSet?.RequestToken);
}
///
/// Returns the remote ip address.
///
+ ///
+ /// Searches for additional headers in the following order:
+ ///
+ /// X-Forwarded-For
+ /// X-Real-IP
+ /// CF-Connecting-IP
+ ///
+ ///
/// The current .
- /// The name of the header to resolve the when behind a proxy (Default: X-Forwarded-For).
+ /// The name of the header to resolve the when behind a proxy.
/// The ip address of the client.
- 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();
- if (!string.IsNullOrWhiteSpace(forwardedHeader) && IPAddress.TryParse(forwardedHeader, out var forwarded))
- return forwarded;
+ string forwardedForAddress = null;
+
+ 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;
}
@@ -40,12 +68,20 @@ namespace Microsoft.AspNetCore.Http
///
/// Returns whether the request was made locally.
///
+ ///
+ /// Searches for additional headers in the following order:
+ ///
+ /// X-Forwarded-For
+ /// X-Real-IP
+ /// CF-Connecting-IP
+ ///
+ ///
/// The current .
- /// The name of the header to resolve the when behind a proxy (Default: X-Forwarded-For).
+ /// The name of the header to resolve the when behind a proxy.
///
- 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);
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1bae954..4ccaa58 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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/),
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_
+## [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
### Fixed
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 84ed1ef..39a9eb1 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -6,8 +6,4 @@
-
-
-
-
diff --git a/UnitTests/AspNetCore/Attributes/IPWhitelistAttributeTests.cs b/UnitTests/AspNetCore/Attributes/IPAllowListAttributeTests.cs
similarity index 91%
rename from UnitTests/AspNetCore/Attributes/IPWhitelistAttributeTests.cs
rename to UnitTests/AspNetCore/Attributes/IPAllowListAttributeTests.cs
index 0545aac..12b2bc3 100644
--- a/UnitTests/AspNetCore/Attributes/IPWhitelistAttributeTests.cs
+++ b/UnitTests/AspNetCore/Attributes/IPAllowListAttributeTests.cs
@@ -14,7 +14,7 @@ namespace UnitTests.AspNetCore.Attributes
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
- public class IPWhitelistAttributeTests
+ public class IPAllowListAttributeTests
{
private Dictionary requestHeaders;
private Dictionary