Skip to content

Commit

Permalink
add AfterAuthenticationMiddleware and AfterAuthorizationMiddleware pr…
Browse files Browse the repository at this point in the history
…operty to OcelotPipelineConfiguration claas for more flexibility in pipieline
  • Loading branch information
ArsalanMoniee committed Jul 26, 2021
1 parent 3ef6abd commit 836e5e9
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 836e5e9

Please sign in to comment.