Added White-/Blacklist Attributes, DateOnly/TimeOnly converters, TcpClientMoq
This commit is contained in:
@@ -38,11 +38,11 @@
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
|
||||
<PackageReference Include="Unclassified.DeepConvert" Version="1.3.0" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.2">
|
||||
<PackageReference Include="Unclassified.DeepConvert" Version="1.4.0" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
103
AMWD.Common.AspNetCore/Attributes/IPBlacklistAttribute.cs
Normal file
103
AMWD.Common.AspNetCore/Attributes/IPBlacklistAttribute.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AMWD.Common.AspNetCore.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements an IP filter. The defined addresses are blocked.
|
||||
/// </summary>
|
||||
public class IPBlacklistAttribute : ActionFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether local (localhost) access is blocked (Default: false).
|
||||
/// </summary>
|
||||
public bool RestrictLocalAccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a configuration key where the blocked IP addresses are defined.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// JSON configuration example:<br/>
|
||||
/// {<br/>
|
||||
/// "ConfigurationKey": [<br/>
|
||||
/// "10.0.0.0/8",<br/>
|
||||
/// "172.16.0.0/12",<br/>
|
||||
/// "fd00:123:abc::13"<br/>
|
||||
/// ]<br/>
|
||||
/// }
|
||||
/// </remarks>
|
||||
public string ConfigurationKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a comma separated list of blocked IP addresses.
|
||||
/// </summary>
|
||||
public string RestrictedIpAddresses { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
base.OnActionExecuting(context);
|
||||
|
||||
if (!RestrictLocalAccess && context.HttpContext.IsLocalRequest())
|
||||
return;
|
||||
|
||||
var remoteIpAddress = context.HttpContext.GetRemoteIpAddress();
|
||||
if (!string.IsNullOrWhiteSpace(RestrictedIpAddresses))
|
||||
{
|
||||
string[] ipAddresses = RestrictedIpAddresses.Split(',');
|
||||
foreach (string ipAddress in ipAddresses)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ipAddress))
|
||||
continue;
|
||||
|
||||
if (MatchesIpAddress(ipAddress, remoteIpAddress))
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var configuration = context.HttpContext.RequestServices.GetService<IConfiguration>();
|
||||
if (!string.IsNullOrWhiteSpace(ConfigurationKey) && configuration != null)
|
||||
{
|
||||
var section = configuration.GetSection(ConfigurationKey);
|
||||
if (!section.Exists())
|
||||
return;
|
||||
|
||||
foreach (var child in section.GetChildren())
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(child.Value))
|
||||
continue;
|
||||
|
||||
if (MatchesIpAddress(child.Value, remoteIpAddress))
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool MatchesIpAddress(string configIpAddress, IPAddress remoteIpAddress)
|
||||
{
|
||||
if (configIpAddress.Contains('/'))
|
||||
{
|
||||
string[] ipNetworkParts = configIpAddress.Split('/');
|
||||
var ip = IPAddress.Parse(ipNetworkParts.First());
|
||||
int prefix = int.Parse(ipNetworkParts.Last());
|
||||
|
||||
var net = new IPNetwork(ip, prefix);
|
||||
return net.Contains(remoteIpAddress);
|
||||
}
|
||||
|
||||
return IPAddress.Parse(configIpAddress).Equals(remoteIpAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
102
AMWD.Common.AspNetCore/Attributes/IPWhitelistAttribute.cs
Normal file
102
AMWD.Common.AspNetCore/Attributes/IPWhitelistAttribute.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AMWD.Common.AspNetCore.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements an IP filter. Only defined addresses are allowed to access.
|
||||
/// </summary>
|
||||
public class IPWhitelistAttribute : ActionFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether local (localhost) access is granted (Default: true).
|
||||
/// </summary>
|
||||
public bool AllowLocalAccess { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a configuration key where the allowed IP addresses are allowed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// JSON configuration example:<br/>
|
||||
/// {<br/>
|
||||
/// "ConfigurationKey": [<br/>
|
||||
/// "10.0.0.0/8",<br/>
|
||||
/// "172.16.0.0/12",<br/>
|
||||
/// "fd00:123:abc::13"<br/>
|
||||
/// ]<br/>
|
||||
/// }
|
||||
/// </remarks>
|
||||
public string ConfigurationKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a comma separated list of allowed IP addresses.
|
||||
/// </summary>
|
||||
public string AllowedIpAddresses { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
base.OnActionExecuting(context);
|
||||
|
||||
if (AllowLocalAccess && context.HttpContext.IsLocalRequest())
|
||||
return;
|
||||
|
||||
var remoteIpAddress = context.HttpContext.GetRemoteIpAddress();
|
||||
if (!string.IsNullOrWhiteSpace(AllowedIpAddresses))
|
||||
{
|
||||
string[] ipAddresses = AllowedIpAddresses.Split(',');
|
||||
foreach (string ipAddress in ipAddresses)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ipAddress))
|
||||
continue;
|
||||
|
||||
if (MatchesIpAddress(ipAddress, remoteIpAddress))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var configuration = context.HttpContext.RequestServices.GetService<IConfiguration>();
|
||||
if (!string.IsNullOrWhiteSpace(ConfigurationKey) && configuration != null)
|
||||
{
|
||||
var section = configuration.GetSection(ConfigurationKey);
|
||||
if (!section.Exists())
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var child in section.GetChildren())
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(child.Value))
|
||||
continue;
|
||||
|
||||
if (MatchesIpAddress(child.Value, remoteIpAddress))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context.Result = new ForbidResult();
|
||||
}
|
||||
|
||||
private static bool MatchesIpAddress(string configIpAddress, IPAddress remoteIpAddress)
|
||||
{
|
||||
if (configIpAddress.Contains('/'))
|
||||
{
|
||||
string[] ipNetworkParts = configIpAddress.Split('/');
|
||||
var ip = IPAddress.Parse(ipNetworkParts.First());
|
||||
int prefix = int.Parse(ipNetworkParts.Last());
|
||||
|
||||
var net = new IPNetwork(ip, prefix);
|
||||
return net.Contains(remoteIpAddress);
|
||||
}
|
||||
|
||||
return IPAddress.Parse(configIpAddress).Equals(remoteIpAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Http
|
||||
/// <summary>
|
||||
/// Retrieves the antiforgery token.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The web context.</param>
|
||||
/// <param name="httpContext">The current <see cref="HttpContext"/>.</param>
|
||||
/// <returns>Name and value of the token.</returns>
|
||||
public static (string Name, string Value) GetAntiforgeryToken(this HttpContext httpContext)
|
||||
{
|
||||
@@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Http
|
||||
/// <summary>
|
||||
/// Returns the remote ip address.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The web context.</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>
|
||||
/// <returns>The ip address of the client.</returns>
|
||||
public static IPAddress GetRemoteIpAddress(this HttpContext httpContext, string headerName = "X-Forwarded-For")
|
||||
@@ -39,10 +39,22 @@ namespace Microsoft.AspNetCore.Http
|
||||
return remote;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the request was made locally.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
/// <returns></returns>
|
||||
public static bool IsLocalRequest(this HttpContext httpContext, string headerName = "X-Forwarded-For")
|
||||
{
|
||||
var remoteIpAddress = httpContext.GetRemoteIpAddress(headerName);
|
||||
return httpContext.Connection.LocalIpAddress.Equals(remoteIpAddress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the return url.
|
||||
/// </summary>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <param name="httpContext">The current <see cref="HttpContext"/>.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetReturnUrl(this HttpContext httpContext)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user