Skip to content

Commit

Permalink
Merge branch 'feature/add-feature-for-ocelot-pipeline-configuration' …
Browse files Browse the repository at this point in the history
…into develop

Cherry picked from ThreeMammals#1497
  • Loading branch information
stefancruz committed Dec 22, 2022
2 parents 3823189 + 836e5e9 commit 93d793f
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/Ocelot/Middleware/OcelotPipelineConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ public class OcelotPipelineConfiguration
/// </value>
public Func<HttpContext, Func<Task>, Task> AuthenticationMiddleware { get; set; }

/// <summary>
/// This is to allow the user to run any extra authentication after the Ocelot authentication
/// kicks in
/// </summary>
/// <value>
/// <placeholder>This is to allow the user to run any extra authentication after the Ocelot authentication
/// kicks in</placeholder>
/// </value>
public Func<HttpContext, Func<Task>, Task> AfterAuthenticationMiddleware { get; set; }

/// <summary>
/// This is to allow the user to run any extra authorization before the Ocelot authentication
/// kicks in
Expand All @@ -56,6 +66,16 @@ public class OcelotPipelineConfiguration
/// </value>
public Func<HttpContext, Func<Task>, Task> AuthorizationMiddleware { get; set; }

/// <summary>
/// This is to allow the user to run any extra authorization after the Ocelot authentication
/// kicks in
/// </summary>
/// <value>
/// <placeholder>This is to allow the user to run any extra authorization after the Ocelot authentication
/// kicks in</placeholder>
/// </value>
public Func<HttpContext, Func<Task>, Task> AfterAuthorizationMiddleware { get; set; }

/// <summary>
/// This allows the user to implement there own query string manipulation logic
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/Ocelot/Middleware/OcelotPipelineExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ public static RequestDelegate BuildOcelotPipeline(this IApplicationBuilder app,
app.Use(pipelineConfiguration.AuthenticationMiddleware);
}

// Allow After authentication logic. The idea being people might want to run something custom after what is built in.
app.UseIfNotNull(pipelineConfiguration.AfterAuthenticationMiddleware);

// The next thing we do is look at any claims transforms in case this is important for authorization
app.UseClaimsToClaimsMiddleware();

Expand All @@ -121,6 +124,9 @@ public static RequestDelegate BuildOcelotPipeline(this IApplicationBuilder app,
app.Use(pipelineConfiguration.AuthorizationMiddleware);
}

// Allow after authorization logic. The idea being people might want to run something custom after what is built in.
app.UseIfNotNull(pipelineConfiguration.AfterAuthorizationMiddleware);

// Now we can run the claims to headers transformation middleware
app.UseClaimsToHeadersMiddleware();

Expand Down
86 changes: 86 additions & 0 deletions test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,50 @@ public void should_call_pre_authorization_middleware()
.And(x => x.ThenTheCounterIs(1))
.BDDfy();
}
[Fact]
public void should_call_after_authorization_middleware()
{
var configuration = new OcelotPipelineConfiguration
{
AfterAuthorizationMiddleware = async (ctx, next) =>
{
_counter++;
await next.Invoke();
}
};

var port = RandomPortFinder.GetRandomPort();

var fileConfiguration = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
DownstreamPathTemplate = "/",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
}
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};

this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, ""))
.And(x => _steps.GivenThereIsAConfiguration(fileConfiguration, _configurationPath))
.And(x => _steps.GivenOcelotIsRunning(configuration))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => x.ThenTheCounterIs(1))
.BDDfy();
}
[Fact]
public void should_call_pre_http_authentication_middleware()
{
Expand Down Expand Up @@ -296,7 +339,50 @@ public void should_call_pre_http_authentication_middleware()
.And(x => x.ThenTheCounterIs(1))
.BDDfy();
}
[Fact]
public void should_call_after_http_authentication_middleware()
{
var configuration = new OcelotPipelineConfiguration
{
AfterAuthenticationMiddleware = async (ctx, next) =>
{
_counter++;
await next.Invoke();
}
};

var port = RandomPortFinder.GetRandomPort();

var fileConfiguration = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
DownstreamPathTemplate = "/",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
}
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};

this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, ""))
.And(x => _steps.GivenThereIsAConfiguration(fileConfiguration, _configurationPath))
.And(x => _steps.GivenOcelotIsRunning(configuration))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => x.ThenTheCounterIs(1))
.BDDfy();
}
[Fact(Skip = "This is just an example to show how you could hook into Ocelot pipeline with your own middleware. At the moment you must use Response.OnCompleted callback and cannot change the response :( I will see if this can be changed one day!")]
public void should_fix_issue_237()
{
Expand Down

0 comments on commit 93d793f

Please sign in to comment.