Add compat switch to opt out of breaking change in AuthZ (#23324)

This commit is contained in:
Hao Kung 2020-06-29 21:50:27 -07:00 committed by GitHub
parent 197f156fcd
commit 1c27ba1bbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 5 deletions

View File

@ -11,6 +11,9 @@ namespace Microsoft.AspNetCore.Authorization
{ {
public class AuthorizationMiddleware public class AuthorizationMiddleware
{ {
// AppContext switch used to control whether HttpContext or endpoint is passed as a resource to AuthZ
private const string SuppressUseHttpContextAsAuthorizationResource = "Microsoft.AspNetCore.Authorization.SuppressUseHttpContextAsAuthorizationResource";
// Property key is used by Endpoint routing to determine if Authorization has run // Property key is used by Endpoint routing to determine if Authorization has run
private const string AuthorizationMiddlewareInvokedWithEndpointKey = "__AuthorizationMiddlewareWithEndpointInvoked"; private const string AuthorizationMiddlewareInvokedWithEndpointKey = "__AuthorizationMiddlewareWithEndpointInvoked";
private static readonly object AuthorizationMiddlewareWithEndpointInvokedValue = new object(); private static readonly object AuthorizationMiddlewareWithEndpointInvokedValue = new object();
@ -61,8 +64,17 @@ namespace Microsoft.AspNetCore.Authorization
return; return;
} }
var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, context, resource: context); object? resource;
if (AppContext.TryGetSwitch(SuppressUseHttpContextAsAuthorizationResource, out var useEndpointAsResource) && useEndpointAsResource)
{
resource = endpoint;
}
else
{
resource = context;
}
var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, context, resource);
var authorizationMiddlewareResultHandler = context.RequestServices.GetRequiredService<IAuthorizationMiddlewareResultHandler>(); var authorizationMiddlewareResultHandler = context.RequestServices.GetRequiredService<IAuthorizationMiddlewareResultHandler>();
await authorizationMiddlewareResultHandler.HandleAsync(_next, context, policy, authorizeResult); await authorizationMiddlewareResultHandler.HandleAsync(_next, context, policy, authorizeResult);
} }

View File

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Authorization.Test.TestObjects; using Microsoft.AspNetCore.Authorization.Test.TestObjects;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq; using Moq;
using Xunit; using Xunit;
@ -314,7 +315,7 @@ namespace Microsoft.AspNetCore.Authorization.Test
} }
[Fact] [Fact]
public async Task AuthZResourceShouldBeHttpContextAndHaveHEndpoint() public async Task AuthZResourceCanBeHttpContextAndHaveEndpoint()
{ {
// Arrange // Arrange
HttpContext resource = null; HttpContext resource = null;
@ -340,6 +341,33 @@ namespace Microsoft.AspNetCore.Authorization.Test
Assert.Equal(endpoint, resource.GetEndpoint()); Assert.Equal(endpoint, resource.GetEndpoint());
} }
[Fact]
public async Task AuthZResourceShouldBeEndpointByDefaultWithCompatSwitch()
{
AppContext.SetSwitch("Microsoft.AspNetCore.Authorization.SuppressUseHttpContextAsAuthorizationResource", isEnabled: true);
// Arrange
object resource = null;
var policy = new AuthorizationPolicyBuilder().RequireAssertion(c =>
{
resource = c.Resource;
return true;
}).Build();
var policyProvider = new Mock<IAuthorizationPolicyProvider>();
policyProvider.Setup(p => p.GetDefaultPolicyAsync()).ReturnsAsync(policy);
var next = new TestRequestDelegate();
var middleware = CreateMiddleware(next.Invoke, policyProvider.Object);
var endpoint = CreateEndpoint(new AuthorizeAttribute());
var context = GetHttpContext(endpoint: endpoint);
// Act
await middleware.Invoke(context);
// Assert
Assert.Equal(endpoint, resource);
}
[Fact] [Fact]
public async Task Invoke_RequireUnknownRoleShouldForbid() public async Task Invoke_RequireUnknownRoleShouldForbid()
{ {
@ -410,7 +438,6 @@ namespace Microsoft.AspNetCore.Authorization.Test
private AuthorizationMiddleware CreateMiddleware(RequestDelegate requestDelegate = null, IAuthorizationPolicyProvider policyProvider = null) private AuthorizationMiddleware CreateMiddleware(RequestDelegate requestDelegate = null, IAuthorizationPolicyProvider policyProvider = null)
{ {
requestDelegate = requestDelegate ?? ((context) => Task.CompletedTask); requestDelegate = requestDelegate ?? ((context) => Task.CompletedTask);
return new AuthorizationMiddleware(requestDelegate, policyProvider); return new AuthorizationMiddleware(requestDelegate, policyProvider);
} }