mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
129 lines
4.2 KiB
C#
129 lines
4.2 KiB
C#
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Routing;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Teknik.Configuration;
|
|
|
|
namespace Teknik.WebCommon.Middleware
|
|
{
|
|
public class BlacklistMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly IMemoryCache _cache;
|
|
|
|
public BlacklistMiddleware(RequestDelegate next, IMemoryCache cache)
|
|
{
|
|
_next = next;
|
|
_cache = cache;
|
|
}
|
|
|
|
public async Task Invoke(HttpContext context, Config config)
|
|
{
|
|
// Beggining of Request
|
|
bool blocked = false;
|
|
string blockReason = string.Empty;
|
|
|
|
#region Detect Blacklisted IPs
|
|
if (!blocked)
|
|
{
|
|
string IPAddr = context.Request.HttpContext.Connection.RemoteIpAddress.ToString();
|
|
if (!string.IsNullOrEmpty(IPAddr))
|
|
{
|
|
StringDictionary badIPs = GetFileData(context, "BlockedIPs", config.IPBlacklistFile);
|
|
|
|
blocked |= (badIPs != null && badIPs.ContainsKey(IPAddr));
|
|
blockReason = $"This IP address ({IPAddr}) has been blacklisted. If you feel this is in error, please contact support@teknik.io for assistance.";
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Detect Blacklisted Referrers
|
|
if (!blocked)
|
|
{
|
|
string referrer = context.Request.Headers["Referer"].ToString();
|
|
string referrerHost = referrer;
|
|
try
|
|
{
|
|
var referrerUri = new Uri(referrer);
|
|
referrerHost = referrerUri.Host;
|
|
} catch
|
|
{ }
|
|
if (!string.IsNullOrEmpty(referrer))
|
|
{
|
|
StringDictionary badReferrers = GetFileData(context, "BlockedReferrers", config.ReferrerBlacklistFile);
|
|
|
|
if (badReferrers != null)
|
|
{
|
|
blocked |= badReferrers.ContainsKey(referrer) || badReferrers.ContainsKey(referrerHost);
|
|
blockReason = $"This referrer ({referrer}) has been blacklisted. If you feel this is in error, please contact support@teknik.io for assistance.";
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
if (blocked)
|
|
{
|
|
// Clear the response
|
|
context.Response.Clear();
|
|
|
|
string jsonResult = JsonConvert.SerializeObject(new { error = new { type = "Blacklist", message = blockReason } });
|
|
await context.Response.WriteAsync(jsonResult);
|
|
return;
|
|
}
|
|
|
|
await _next.Invoke(context);
|
|
|
|
// End of request
|
|
}
|
|
|
|
public StringDictionary GetFileData(HttpContext context, string key, string filePath)
|
|
{
|
|
StringDictionary data;
|
|
if (!_cache.TryGetValue(key, out data))
|
|
{
|
|
data = GetFileLines(filePath);
|
|
_cache.Set(key, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
public StringDictionary GetFileLines(string configPath)
|
|
{
|
|
StringDictionary retval = new StringDictionary();
|
|
if (File.Exists(configPath))
|
|
{
|
|
using (StreamReader sr = new StreamReader(configPath))
|
|
{
|
|
String line;
|
|
while ((line = sr.ReadLine()) != null)
|
|
{
|
|
line = line.Trim();
|
|
if (line.Length != 0)
|
|
{
|
|
retval.Add(line, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
public static class BlacklistMiddlewareExtensions
|
|
{
|
|
public static IApplicationBuilder UseBlacklist(this IApplicationBuilder builder)
|
|
{
|
|
return builder.UseMiddleware<BlacklistMiddleware>();
|
|
}
|
|
}
|
|
}
|