Sfoglia il codice sorgente

測試頁面僅限白名單內IP使用

master
Joanne.Chuang 2 settimane fa
parent
commit
081d0952f1
8 ha cambiato i file con 182 aggiunte e 2 eliminazioni
  1. +2
    -2
      Altob.NtuInvoiceGateway/Altob.NtuInvoiceGateway.csproj
  2. +85
    -0
      Altob.NtuInvoiceGateway/Middleware/IpWhitelistMiddleware.cs
  3. +6
    -0
      Altob.NtuInvoiceGateway/Models/InvoiceApiOptions.cs
  4. +7
    -0
      Altob.NtuInvoiceGateway/Models/IpWhitelistOptions.cs
  5. +6
    -0
      Altob.NtuInvoiceGateway/Program.cs
  6. +36
    -0
      Altob.NtuInvoiceGateway/appsettings.Production.json
  7. +36
    -0
      Altob.NtuInvoiceGateway/appsettings.Staging.json
  8. +4
    -0
      Altob.NtuInvoiceGateway/appsettings.json

+ 2
- 2
Altob.NtuInvoiceGateway/Altob.NtuInvoiceGateway.csproj Vedi File

@@ -7,8 +7,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="6.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
</ItemGroup>

</Project>

+ 85
- 0
Altob.NtuInvoiceGateway/Middleware/IpWhitelistMiddleware.cs Vedi File

@@ -0,0 +1,85 @@
using System.Net;
using Altob.NtuInvoiceGateway.Models;
using Microsoft.Extensions.Options;

namespace Altob.NtuInvoiceGateway.Middleware;

public class IpWhitelistMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<IpWhitelistMiddleware> _logger;
private readonly IpWhitelistOptions _ipWhitelistOptions;

public IpWhitelistMiddleware(
RequestDelegate next,
ILogger<IpWhitelistMiddleware> logger,
IOptions<IpWhitelistOptions> ipWhitelistOptions)
{
_next = next;
_logger = logger;
_ipWhitelistOptions = ipWhitelistOptions.Value;
}

public async Task InvokeAsync(HttpContext context)
{
// 如果 IP 白名單未啟用,直接通過
if (!_ipWhitelistOptions.Enabled)
{
await _next(context);
return;
}

// 只對 Test 開頭的頁面進行 IP 白名單檢查
var path = context.Request.Path.Value ?? string.Empty;
if (!path.StartsWith("/Test", StringComparison.OrdinalIgnoreCase))
{
await _next(context);
return;
}

var remoteIp = context.Connection.RemoteIpAddress;
var clientIp = GetClientIp(context);

_logger.LogDebug("IP Whitelist check for Test page - Path: {Path}, RemoteIp: {RemoteIp}, ClientIp: {ClientIp}",
path, remoteIp, clientIp);

// 檢查 RemoteIp 或 ClientIp 是否在白名單中
var isAllowed = false;

if (remoteIp != null && IsIpAllowed(remoteIp.ToString()))
{
isAllowed = true;
}
else if (clientIp != null && IsIpAllowed(clientIp))
{
isAllowed = true;
}

if (!isAllowed)
{
_logger.LogWarning("{ServiceName} - {ActionName} - {CallerIp} - {ClientIp} - IP access denied to Test page: {Path}",
"NtuInvoiceGateway", "IpWhitelistCheck", remoteIp?.ToString() ?? "Unknown", clientIp, path);

context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync("Access denied. Your IP address is not allowed to access test pages.");
return;
}

await _next(context);
}

private bool IsIpAllowed(string ipAddress)
{
return _ipWhitelistOptions.AllowedIps.Contains(ipAddress);
}

private string? GetClientIp(HttpContext context)
{
var forwardedFor = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
if (!string.IsNullOrEmpty(forwardedFor))
{
return forwardedFor.Split(',').FirstOrDefault()?.Trim();
}
return null;
}
}

+ 6
- 0
Altob.NtuInvoiceGateway/Models/InvoiceApiOptions.cs Vedi File

@@ -0,0 +1,6 @@
namespace Altob.NtuInvoiceGateway.Models;

public class InvoiceApiOptions
{
public string Endpoint { get; set; } = string.Empty;
}

+ 7
- 0
Altob.NtuInvoiceGateway/Models/IpWhitelistOptions.cs Vedi File

@@ -0,0 +1,7 @@
namespace Altob.NtuInvoiceGateway.Models;

public class IpWhitelistOptions
{
public bool Enabled { get; set; }
public List<string> AllowedIps { get; set; } = new();
}

+ 6
- 0
Altob.NtuInvoiceGateway/Program.cs Vedi File

@@ -1,3 +1,5 @@
using Altob.NtuInvoiceGateway.Middleware;
using Altob.NtuInvoiceGateway.Models;
using Serilog;

var builder = WebApplication.CreateBuilder(args);
@@ -19,6 +21,8 @@ builder.Services.Configure<Altob.NtuInvoiceGateway.Models.CompanyInfo>(
builder.Configuration.GetSection("CompanyInfo"));
builder.Services.Configure<Altob.NtuInvoiceGateway.Models.InvoiceApiOptions>(
builder.Configuration.GetSection("InvoiceApi"));
builder.Services.Configure<IpWhitelistOptions>(
builder.Configuration.GetSection("IpWhitelist"));

var app = builder.Build();

@@ -36,6 +40,8 @@ try

app.UseRouting();

app.UseMiddleware<IpWhitelistMiddleware>();

app.UseAuthorization();

app.MapStaticAssets();


+ 36
- 0
Altob.NtuInvoiceGateway/appsettings.Production.json Vedi File

@@ -0,0 +1,36 @@
{
"DetailedErrors": false,
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.AspNetCore": "Error"
}
},
"Serilog": {
"Using": [ "Serilog.Sinks.Seq" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341",
"apiKey": ""
}
}
],
"Enrich": [ "FromLogContext" ]
},
"IpWhitelist": {
"Enabled": true,
"AllowedIps": [ "127.0.0.1", "::1","61.219.172.82","61.222.237.97","125.227.77.79" ]
},
"InvoiceApi": {
"Endpoint": "http://140.112.143.162:22055/api/Intella/invoiceInfo"
}
}

+ 36
- 0
Altob.NtuInvoiceGateway/appsettings.Staging.json Vedi File

@@ -0,0 +1,36 @@
{
"DetailedErrors": false,
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.AspNetCore": "Error"
}
},
"Serilog": {
"Using": [ "Serilog.Sinks.Seq" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341",
"apiKey": ""
}
}
],
"Enrich": [ "FromLogContext" ]
},
"IpWhitelist": {
"Enabled": true,
"AllowedIps": [ "127.0.0.1", "::1" ]
},
"InvoiceApi": {
"Endpoint": "http://192.168.110.72:22055/api/Intella/invoiceInfo"
}
}

+ 4
- 0
Altob.NtuInvoiceGateway/appsettings.json Vedi File

@@ -25,6 +25,10 @@
],
"Enrich": [ "FromLogContext" ]
},
"IpWhitelist": {
"Enabled": true,
"AllowedIps": [ "127.0.0.1", "::1" ]
},
"AllowedHosts": "*",
"CompanyInfo": {
"Name": "國立台灣大學臨時停車場",


Loading…
Annulla
Salva