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
{
// 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
private const string AuthorizationMiddlewareInvokedWithEndpointKey = "__AuthorizationMiddlewareWithEndpointInvoked";
private static readonly object AuthorizationMiddlewareWithEndpointInvokedValue = new object();
@ -18,7 +21,7 @@ namespace Microsoft.AspNetCore.Authorization
private readonly RequestDelegate _next;
private readonly IAuthorizationPolicyProvider _policyProvider;
public AuthorizationMiddleware(RequestDelegate next, IAuthorizationPolicyProvider policyProvider)
public AuthorizationMiddleware(RequestDelegate next, IAuthorizationPolicyProvider policyProvider)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_policyProvider = policyProvider ?? throw new ArgumentNullException(nameof(policyProvider));
@ -61,8 +64,17 @@ namespace Microsoft.AspNetCore.Authorization
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>();
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.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
@ -314,7 +315,7 @@ namespace Microsoft.AspNetCore.Authorization.Test
}
[Fact]
public async Task AuthZResourceShouldBeHttpContextAndHaveHEndpoint()
public async Task AuthZResourceCanBeHttpContextAndHaveEndpoint()
{
// Arrange
HttpContext resource = null;
@ -340,6 +341,33 @@ namespace Microsoft.AspNetCore.Authorization.Test
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]
public async Task Invoke_RequireUnknownRoleShouldForbid()
{
@ -410,7 +438,6 @@ namespace Microsoft.AspNetCore.Authorization.Test
private AuthorizationMiddleware CreateMiddleware(RequestDelegate requestDelegate = null, IAuthorizationPolicyProvider policyProvider = null)
{
requestDelegate = requestDelegate ?? ((context) => Task.CompletedTask);
return new AuthorizationMiddleware(requestDelegate, policyProvider);
}