Skip to content

Commit e231c61

Browse files
authored
Re-run routing for implicit middlewares that require endpoints (#49732)
* Re-run routing for implicit middlewares that require endpoints * Address feedback from peer review * Update generated code comment
1 parent 080dea9 commit e231c61

File tree

8 files changed

+435
-5
lines changed

8 files changed

+435
-5
lines changed

src/Antiforgery/src/AntiforgeryApplicationBuilderExtensions.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
using Microsoft.AspNetCore.Antiforgery;
55
using Microsoft.AspNetCore.Antiforgery.Internal;
6+
using Microsoft.AspNetCore.Routing;
7+
using Microsoft.Extensions.DependencyInjection;
68

79
namespace Microsoft.AspNetCore.Builder;
810

@@ -24,6 +26,19 @@ public static IApplicationBuilder UseAntiforgery(this IApplicationBuilder builde
2426
builder.VerifyAntiforgeryServicesAreRegistered();
2527

2628
builder.Properties[AntiforgeryMiddlewareSetKey] = true;
29+
30+
// The anti-forgery middleware adds annotations to HttpContext.Items to indicate that it has run
31+
// that will be validated by the EndpointsRoutingMiddleware later. To do this, we need to ensure
32+
// that routing has run and set the endpoint feature on the HttpContext associated with the request.
33+
if (builder.Properties.TryGetValue(RerouteHelper.GlobalRouteBuilderKey, out var routeBuilder) && routeBuilder is not null)
34+
{
35+
return builder.Use(next =>
36+
{
37+
var newNext = RerouteHelper.Reroute(builder, routeBuilder, next);
38+
var antiforgery = builder.ApplicationServices.GetRequiredService<IAntiforgery>();
39+
return new AntiforgeryMiddleware(antiforgery, newNext).Invoke;
40+
});
41+
}
2742
builder.UseMiddleware<AntiforgeryMiddleware>();
2843

2944
return builder;

src/Antiforgery/src/Microsoft.AspNetCore.Antiforgery.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@
2626

2727
<ItemGroup>
2828
<Compile Include="$(SharedSourceRoot)HttpMethodExtensions.cs" LinkBase="Shared"/>
29+
<Compile Include="$(SharedSourceRoot)Reroute.cs" LinkBase="Shared"/>
2930
</ItemGroup>
3031
</Project>

src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebApplicationTests.cs

Lines changed: 373 additions & 3 deletions
Large diffs are not rendered by default.

src/Http/Http.Extensions/src/RequestDelegateFactory.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,12 +2014,18 @@ private static Expression BindComplexParameterFromFormItem(
20142014
FormDataMapperMapMethod.MakeGenericMethod(parameter.ParameterType),
20152015
formReader,
20162016
Expression.Constant(FormDataMapperOptions));
2017-
// ArrayPool<char>.Shared.Return(form_buffer, false);
2017+
// if (form_buffer != null)
2018+
// {
2019+
// ArrayPool<char>.Shared.Return(form_buffer, false);
2020+
// }
20182021
var returnBufferExpr = Expression.Call(
20192022
Expression.Property(null, typeof(ArrayPool<char>).GetProperty(nameof(ArrayPool<char>.Shared))!),
20202023
ArrayPoolSharedReturnMethod,
20212024
formBuffer,
20222025
Expression.Constant(false));
2026+
var conditionalReturnBufferExpr = Expression.IfThen(
2027+
Expression.NotEqual(formBuffer, Expression.Constant(null)),
2028+
returnBufferExpr);
20232029

20242030
return Expression.Block(
20252031
new[] { formArgument, formReader, formDict, formBuffer },
@@ -2028,7 +2034,7 @@ private static Expression BindComplexParameterFromFormItem(
20282034
processFormExpr,
20292035
initializeReaderExpr,
20302036
Expression.Assign(formArgument, invokeMapMethodExpr)),
2031-
returnBufferExpr),
2037+
conditionalReturnBufferExpr),
20322038
formArgument
20332039
);
20342040
}

src/Security/Authentication/Core/src/AuthAppBuilderExtensions.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using Microsoft.AspNetCore.Authentication;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.AspNetCore.Routing;
57

68
namespace Microsoft.AspNetCore.Builder;
79

@@ -22,6 +24,20 @@ public static IApplicationBuilder UseAuthentication(this IApplicationBuilder app
2224
ArgumentNullException.ThrowIfNull(app);
2325

2426
app.Properties[AuthenticationMiddlewareSetKey] = true;
27+
28+
// The authentication middleware adds annotation to HttpContext.Items to indicate that it has run
29+
// that will be validated by the EndpointsRoutingMiddleware later. To do this, we need to ensure
30+
// that routing has run and set the endpoint feature on the HttpContext associated with the request.
31+
if (app.Properties.TryGetValue(RerouteHelper.GlobalRouteBuilderKey, out var routeBuilder) && routeBuilder is not null)
32+
{
33+
return app.Use(next =>
34+
{
35+
var newNext = RerouteHelper.Reroute(app, routeBuilder, next);
36+
var authenticationSchemeProvider = app.ApplicationServices.GetRequiredService<IAuthenticationSchemeProvider>();
37+
return new AuthenticationMiddleware(newNext, authenticationSchemeProvider).Invoke;
38+
});
39+
}
40+
2541
return app.UseMiddleware<AuthenticationMiddleware>();
2642
}
2743
}

src/Security/Authentication/Core/src/Microsoft.AspNetCore.Authentication.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
<ItemGroup>
1414
<Compile Include="$(SharedSourceRoot)SecurityHelper\**\*.cs" />
15+
<Compile Include="$(SharedSourceRoot)Reroute.cs" />
1516
</ItemGroup>
1617

1718
<ItemGroup>

src/Security/Authorization/Policy/src/AuthorizationAppBuilderExtensions.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
using Microsoft.AspNetCore.Authorization;
55
using Microsoft.AspNetCore.Authorization.Policy;
6+
using Microsoft.AspNetCore.Routing;
67
using Microsoft.Extensions.DependencyInjection;
8+
using Microsoft.Extensions.Logging;
79

810
namespace Microsoft.AspNetCore.Builder;
911

@@ -30,6 +32,24 @@ public static IApplicationBuilder UseAuthorization(this IApplicationBuilder app)
3032
VerifyServicesRegistered(app);
3133

3234
app.Properties[AuthorizationMiddlewareSetKey] = true;
35+
36+
// The authorization middleware adds annotation to HttpContext.Items to indicate that it has run
37+
// that will be validated by the EndpointsRoutingMiddleware later. To do this, we need to ensure
38+
// that routing has run and set the endpoint feature on the HttpContext associated with the request.
39+
if (app.Properties.TryGetValue(RerouteHelper.GlobalRouteBuilderKey, out var routeBuilder) && routeBuilder is not null)
40+
{
41+
return app.Use(next =>
42+
{
43+
var newNext = RerouteHelper.Reroute(app, routeBuilder, next);
44+
var authorizationPolicyProvider = app.ApplicationServices.GetRequiredService<IAuthorizationPolicyProvider>();
45+
var logger = app.ApplicationServices.GetRequiredService<ILogger<AuthorizationMiddleware>>();
46+
return new AuthorizationMiddlewareInternal(newNext,
47+
app.ApplicationServices,
48+
authorizationPolicyProvider,
49+
logger).Invoke;
50+
});
51+
}
52+
3353
return app.UseMiddleware<AuthorizationMiddlewareInternal>();
3454
}
3555

src/Security/Authorization/Policy/src/Microsoft.AspNetCore.Authorization.Policy.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<ItemGroup>
1414
<Compile Include="$(SharedSourceRoot)SecurityHelper\**\*.cs" />
1515
<Compile Include="..\..\..\..\Http\Routing\src\DataSourceDependentCache.cs" Link="DataSourceDependentCache.cs" />
16+
<Compile Include="$(SharedSourceRoot)Reroute.cs" />
1617
</ItemGroup>
1718

1819
<ItemGroup>

0 commit comments

Comments
 (0)