ASP.NET Core - Bloqueando endereços IP
 Hoje veremos como bloquear endereços IP em uma aplicação ASP.NET Core Web API.


O bloqueio de endereços IP é um recurso útil se quisermos garantir que usuários mal-intencionados conhecidos não tenham acesso ao nosso aplicativo. Essa abordagem permite o acesso a API e define apenas a lista de endereços IP a serem bloqueados pelo nosso aplicativo.
 


 


Da mesma forma, podemos decidir permitir que apenas uma determinada lista de endereços IP acesse nosso aplicativo, adotando a abordagem de bloquear o acesso a todos e permitir que apenas entidades conhecidas e confiáveis acessem nossa API.

 

Ambos os métodos são maneiras válidas de restringir o acesso ao nosso aplicativo com base no endereço IP e, logicamente, no código, há pouca diferença na implementação.

Formas de bloquer o endereço IP


A ASP.NET Core nos fornece duas maneiras diferentes de bloquear o acesso de endereços IP aos nossos aplicativos.

Em primeiro lugar, podemos optar por implementar o bloqueio em todo o aplicativo para cada solicitação que nosso aplicativo recebe, por meio do  Middleware ASP.NET Core .

 

A segunda opção é usar filtros de ação, permitindo que sejamos mais seletivos sobre quais controladores ou até endpoints específicos desejamos aplicar o bloqueio.

 

Vamos apresentar uma implementação das duas opções.

 

Criando o projeto API
 

Vamos usar o VS 2022 no ambiente do .NET6 e criar um projeto ASP.NET Core Web API chamado ApiBloqueioIP.

 

No projeto vamos criar um controlador chamado BloqueioIPController e definir dois endpoints que iremos usar para teste:

 

using Microsoft.AspNetCore.Mvc;
namespace ApiBloqueioIp.Controllers;
[Route("api/[controller]")]
[ApiController]
public class BloqueioIPController : ControllerBase
{
    [HttpGet("desbloqueado")]
    public string Desbloqueado()
    {
        return $"Acesso Desbloqueado para este endpoint : {DateTime.Now}";
    }
    [HttpGet("bloqueado")]
    public string Bloqueado()
    {
        return $"Acesso BLOQUEADO para este endpoint : {DateTime.Now}";
    }
}

 

Implementando o serviço para bloquear IPs

 

Agora vamos criar um serviço que pode usar tanto middleware como Action Filters para realizar o bloqueio de ips.

 

Crie uma pasta Services no projeto e nesta pasta vamos criar a interface IBloquearIPService :
 

using System.Net;
namespace ApiBloqueioIp.Services;
public interface IBloquearIPService
{
    bool EstaBloqueado(IPAddress ipAddress);
}


A seguir vamos criar a classe BloquearIPService :

 

using System.Net;
namespace ApiBloqueioIp.Services;
public class BloquearIPService : IBloquearIPService
{
    private readonly List<string> _IpsBloqueados;
    public BloquearIPService(IConfiguration configuration)
    {
        var IpsBloqueados = configuration.GetValue<string>("IPsBloqueados");
        _IpsBloqueados = IpsBloqueados.Split(',').ToList();
    }

    public bool EstaBloqueado(IPAddress ipAddress) => _IpsBloqueados.Contains(ipAddress.ToString());
}

 

Neste código injetamos a interface IConfiguration e a usamos para obter o valor dos Ips bloqueados em IPsBloqueados do arquivo appsettings.json, que é uma lista de endereços IP separados por vírgula.

Finalmente, chamamos o método
EstaBloqueado() para verificar se nossa lista _IpsBloqueados contém o parâmetro ipAddress.

 

Precisamos agora definir no arquivo appsettings.json uma seção chamada :  IPsBloqueados onde iremos definir os IPs que desejamos bloquear:

 

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "IPsBloqueados": ""
}

Para conlcuir vamos registrar nosso serviço como um serviço com tempo de vida Transient na classe Program:

builder.Services.AddTransient<I
BloquearIPService , BloquearIPService >();

Com o serviço criado, vamos ver como bloquear o acesso ao nosso aplicativo usando o middleware ASP.NET Core.

Criando um middleware de bloqueio de IP

 

Vamos criar agora um middleware para realizar o bloqueio de IPs criando a classe BloquearIPMiddleware na pasta Services :

 

using System.Net;
namespace ApiBloqueioIp.Services;
public class BloquearIPMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IBloquearIPService _bloquearIpService;
    public BloquearIPMiddleware(RequestDelegate next, IBloquearIPService bloquearIpService)
    {
        _next = next;
        _bloquearIpService = bloquearIpService;
    }
    public async Task Invoke(HttpContext context)
    {
        var remoteIp = context.Connection.RemoteIpAddress;
        var estaBloqueado = _bloquearIpService.EstaBloqueado(remoteIp!);
        if (estaBloqueado)
        {
            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            return;
        }
        await _next.Invoke(context);
    }
}

 

Entendendo o código :

 

Primeiro, injetamos RequestDelegate, que é uma função que pode processar uma solicitação HTTP. Ele representa o próximo delegado no pipeline que manipulará a solicitação HTTP.

A seguir injetamos a interface
IBloquearIPService .

Em seguida, o método Invoke() toma o HttpContext atual como parâmetro, o que nos permite recuperar o endereço IP do request atual por meio de context.Connection.RemoteIpAddress.

Depois  passamos esse endereço IP para o método
EstaBloqueado() para verificar se o IP deve ser bloqueado e, se for, configuramos context.Response.StatusCode para Forbidden e retornamos do método.

 

Para concluir se o endereço IP não estiver bloqueado, chamamos Invoke() em RequestDelegate para garantir que a solicitação continue pelo restante do pipeline de middleware.

Com nosso middleware definido, podemos adicioná-lo ao pipeline na classe Program:

 

...
var app = builder.Build();
//middleware para bloquear ips
app.UseMiddleware<BloquearIPMiddleware>();

...


Testando a implementação

 

Para testar vamos criar uma aplicação ASP .NET Core MVC no VS 2022 e definir o seguinte código na classe Program:

 

var baseUrl = "https://localhost:7224/";

builder.Services.AddScoped(sp => new HttpClient
{
   BaseAddress =
new Uri(baseUrl)
});

 

Aqui definimos o endereço para acessar a nossa API que esta atendendo em https://localhost:7224/

 

A seguir no controlador HomeController vamos criar o método Action ConsomeAPI com o seguinte código:

 

public async Task<IActionResult> ConsomeAPI()
    {
        var response = await _httpClient.GetAsync($"api/bloqueioip/bloqueado");
        if (response.IsSuccessStatusCode)
        {
            if (response.StatusCode == HttpStatusCode.NoContent)
            {
                ViewBag.Resultado = $"Status Code : {response.StatusCode}";
                return View();
            }
            var resultado = await response.Content.ReadAsStringAsync();
            ViewBag.Resultado = resultado;
        }
        else
        {
            var message = await response.Content.ReadAsStringAsync();
            ViewBag.Resultado = $"Status Code : {response.StatusCode} {message}";
            _logger.LogError($" Não foi possivel acessar o endpoint  - {message}");
        }
        return View();
    }

 

A nossa view ConsomeAPI é bem simples e apenas exibe o resultado :

 

@model string

<p class="text-danger">

<h3>@ViewBag.Resultado</h3>

</p>


Para restringir o acesso ao nosso IP vamos definir no arquivo appsettings da API os seguintes valores :

 

{
"Logging": {
  
"LogLevel": {
     
"Default": "Information",
          
"Microsoft.AspNetCore": "Warning"
    }
},
"AllowedHosts": "*",
"IPsBloqueados": "127.0.0.0,::1"
}

 

Executando o projeto teremos a pagina inicial:

 

 

Tentando acessar qualquer um dos endpoints da API iremos obter o resultado abaixo:
 


Usando o middleware bloqueamos o IP para acessar todos os endpoints da nossa API.

 

Na próxima parte do artigo veremos como usar um filtro para restringir o acesso de um IP.
 

Pegue o código aqui :   ApiBloqueioIp.zip ... 

 

"Porque os que são segundo a carne inclinam-se para as coisas da carne; mas os que são segundo o Espírito para as coisas do Espírito. Porque a inclinação da carne é morte; mas a inclinação do Espírito é vida e paz."
Romanos 8:5,6


Referências:


José Carlos Macoratti