Skip to content

Commit ba2aab1

Browse files
committed
feat: Enhance LocalPortFiltering to support multiple allowed ports.
- Updated the `AllowPort` property to `List<int> AllowPorts` to handle multiple allowed ports. - Updated documentation and comments accordingly.
1 parent af2973c commit ba2aab1

9 files changed

Lines changed: 34 additions & 19 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ app.UseLocalPortFiltering();
3333

3434
// Define a GET endpoint with port filtering
3535
app.MapGet("/service1", () => "Welcome to Service 1")
36-
.RequireLocalPortFiltering(allowPort: 5105);
36+
.RequireLocalPortFiltering(allowPorts: 5105);
3737

3838
// Define another GET endpoint without port filtering
3939
app.MapGet("/service2", () => "Welcome to Service 2");
@@ -54,7 +54,7 @@ using Microsoft.AspNetCore.Mvc;
5454
public class SampleController : ControllerBase
5555
{
5656
[HttpGet]
57-
[LocalPortFiltering(allowPort: 5105)]
57+
[LocalPortFiltering(allowPorts: 5105)]
5858
public IActionResult Get()
5959
{
6060
return Ok("This endpoint is only accessible on port 5105.");
@@ -84,7 +84,7 @@ Use `RequireLocalPortFiltering`
8484
You can apply port-based filtering to specific endpoints:
8585

8686
```csharp
87-
app.MapHealthChecks("/healthz").RequireLocalPortFiltering(allowPort: 5105);
87+
app.MapHealthChecks("/healthz").RequireLocalPortFiltering(allowPorts: 5105);
8888
```
8989

9090
**Combine with Conditional Middleware**

sample/LocalPortFilteringDemo/Controllers/WeatherForecastController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public WeatherForecastController(ILogger<WeatherForecastController> logger)
1919
}
2020

2121
[HttpGet(Name = "GetWeatherForecast")]
22-
[LocalPortFiltering(allowPort: 7239)]
22+
[LocalPortFiltering(allowPorts: 7239)]
2323
public IEnumerable<WeatherForecast> Get()
2424
{
2525
return Enumerable.Range(1, 5).Select(index => new WeatherForecast

sample/LocalPortFilteringDemo/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
app.UseAuthorization();
1717
app.UseLocalPortFiltering();
1818

19-
app.MapHealthChecks("/healthz").RequireLocalPortFiltering(allowPort: 5105);
19+
app.MapHealthChecks("/healthz").RequireLocalPortFiltering(allowPorts: 5105);
2020
app.MapControllers();
2121

2222
app.Run();

src/LocalPortFiltering.AspNetCore/ILocalPortFilteringData.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
public interface ILocalPortFilteringData
77
{
88
/// <summary>
9-
/// Gets the port number that is allowed through the filter.
9+
/// Gets the list of port numbers that are allowed through the filter.
1010
/// </summary>
11-
int AllowPort { get; }
11+
IReadOnlyList<int> AllowPorts { get; }
1212
}
1313

src/LocalPortFiltering.AspNetCore/LocalPortFilteringAttribute.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@
55
public class LocalPortFilteringAttribute : Attribute, ILocalPortFilteringData
66
{
77
/// <inheritdoc />
8-
public int AllowPort { get; }
8+
public IReadOnlyList<int> AllowPorts { get; }
99

1010
/// <summary>
1111
/// Initializes a new instance of the <see cref="LocalPortFilteringAttribute"/> class.
1212
/// </summary>
1313
/// <param name="allowPort">The port number that is allowed through the filter.</param>
1414
public LocalPortFilteringAttribute(int allowPort)
15+
: this([allowPort])
1516
{
16-
AllowPort = allowPort;
17+
}
18+
19+
/// <summary>
20+
/// Initializes a new instance of the <see cref="LocalPortFilteringAttribute"/> class.
21+
/// </summary>
22+
/// <param name="allowPorts">The port numbers that is allowed through the filter.</param>
23+
public LocalPortFilteringAttribute(params int[] allowPorts)
24+
{
25+
ArgumentNullException.ThrowIfNull(allowPorts);
26+
27+
AllowPorts = allowPorts.ToArray();
1728
}
1829
}

src/LocalPortFiltering.AspNetCore/LocalPortFilteringEndpointConventionBuilderExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ public static class LocalPortFilteringEndpointConventionBuilderExtensions
1212
/// </summary>
1313
/// <typeparam name="TBuilder">The type of the builder.</typeparam>
1414
/// <param name="builder">The endpoint convention builder instance.</param>
15-
/// <param name="allowPort">The allowed port for local port filtering.</param>
15+
/// <param name="allowPorts">The allowed ports for local port filtering.</param>
1616
/// <returns>The updated endpoint convention builder.</returns>
17-
public static TBuilder RequireLocalPortFiltering<TBuilder>(this TBuilder builder, int allowPort)
17+
public static TBuilder RequireLocalPortFiltering<TBuilder>(this TBuilder builder, params int[] allowPorts)
1818
where TBuilder : IEndpointConventionBuilder
1919
{
2020
ArgumentNullException.ThrowIfNull(builder);
2121

22-
RequireLocalPortFilteringCore(builder, new LocalPortFilteringAttribute(allowPort));
22+
RequireLocalPortFilteringCore(builder, new LocalPortFilteringAttribute(allowPorts));
2323

2424
return builder;
2525
}

src/LocalPortFiltering.AspNetCore/LocalPortFilteringMiddleware.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public Task Invoke(HttpContext context)
5151
if (exceptionHandler == null)
5252
return m_Next(context);
5353

54-
if (exceptionHandler.AllowPort != context.Connection.LocalPort)
54+
if (!exceptionHandler.AllowPorts.Contains(context.Connection.LocalPort))
5555
return HostValidationFailed(context);
5656

5757
return m_Next(context);

test/LocalPortFiltering.AspNetCore.Tests/LocalPortFilteringConventionBuilderExtensionsTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.AspNetCore.Builder;
2-
using Microsoft.AspNetCore.Cors.Infrastructure;
32
using Microsoft.AspNetCore.Http;
43

54
namespace LocalPortFiltering.AspNetCore.Tests;
@@ -12,7 +11,7 @@ public void RequireLocalPort_AllowPort_MetadataAdded()
1211
var testConventionBuilder = new TestEndpointConventionBuilder();
1312

1413
// Act
15-
testConventionBuilder.RequireLocalPortFiltering(80);
14+
testConventionBuilder.RequireLocalPortFiltering([80, 443]);
1615

1716
// Assert
1817
var addCorsPolicy = Assert.Single(testConventionBuilder.Conventions);
@@ -23,7 +22,8 @@ public void RequireLocalPort_AllowPort_MetadataAdded()
2322

2423
var metadata = endpoint.Metadata.GetMetadata<ILocalPortFilteringData>();
2524
Assert.NotNull(metadata);
26-
Assert.Equal(80, metadata.AllowPort);
25+
Assert.Contains(80, metadata.AllowPorts);
26+
Assert.Contains(443, metadata.AllowPorts);
2727
}
2828

2929
[Fact]

test/LocalPortFiltering.AspNetCore.Tests/LocalPortFilteringMiddlewareTests.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,13 @@ public async Task TestLocalPortFiltering_DefaultBehavior()
4242
}
4343

4444
[Theory]
45-
[InlineData(200, 80, 80)]
46-
[InlineData(403, 8080, 80)]
47-
public async Task TestLocalPortFiltering_RejectsBlockedPort(int status, int localPort, int allowPort)
45+
[InlineData(200, 443, new int[] { 443 })]
46+
[InlineData(403, 80, new int[] { 443 })]
47+
[InlineData(200, 3000, new int[] { 3000, 3001 })]
48+
[InlineData(403, 4000, new int[] { 3000, 3001 })]
49+
[InlineData(200, 1005, new int[] { 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010 })]
50+
[InlineData(403, 1500, new int[] { 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010 })]
51+
public async Task TestLocalPortFiltering_RejectsBlockedPort(int status, int localPort, int[] allowPort)
4852
{
4953
// Arrange
5054
var options = new LocalPortFilteringOptions();

0 commit comments

Comments
 (0)