Add AuthZHandlerContextFactory
This commit is contained in:
parent
6f15d616a8
commit
d291bb7c24
|
|
@ -42,32 +42,32 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
/// <summary>
|
||||
/// The collection of all the <see cref="IAuthorizationRequirement"/> for the current authorization action.
|
||||
/// </summary>
|
||||
public IEnumerable<IAuthorizationRequirement> Requirements { get; }
|
||||
public virtual IEnumerable<IAuthorizationRequirement> Requirements { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ClaimsPrincipal"/> representing the current user.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal User { get; }
|
||||
public virtual ClaimsPrincipal User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The optional resource to evaluate the <see cref="AuthorizationHandlerContext.Requirements"/> against.
|
||||
/// </summary>
|
||||
public object Resource { get; }
|
||||
public virtual object Resource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the requirements that have not yet been marked as succeeded.
|
||||
/// </summary>
|
||||
public IEnumerable<IAuthorizationRequirement> PendingRequirements { get { return _pendingRequirements; } }
|
||||
public virtual IEnumerable<IAuthorizationRequirement> PendingRequirements { get { return _pendingRequirements; } }
|
||||
|
||||
/// <summary>
|
||||
/// Flag indicating whether the current authorization processing has failed.
|
||||
/// </summary>
|
||||
public bool HasFailed { get { return _failCalled; } }
|
||||
public virtual bool HasFailed { get { return _failCalled; } }
|
||||
|
||||
/// <summary>
|
||||
/// Flag indicating whether the current authorization processing has succeeded.
|
||||
/// </summary>
|
||||
public bool HasSucceeded
|
||||
public virtual bool HasSucceeded
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
/// Called to indicate <see cref="AuthorizationHandlerContext.HasSucceeded"/> will
|
||||
/// never return true, even if all requirements are met.
|
||||
/// </summary>
|
||||
public void Fail()
|
||||
public virtual void Fail()
|
||||
{
|
||||
_failCalled = true;
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
/// successfully evaluated.
|
||||
/// </summary>
|
||||
/// <param name="requirement">The requirement whose evaluation has succeeded.</param>
|
||||
public void Succeed(IAuthorizationRequirement requirement)
|
||||
public virtual void Succeed(IAuthorizationRequirement requirement)
|
||||
{
|
||||
_succeedCalled = true;
|
||||
_pendingRequirements.Remove(requirement);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationService, DefaultAuthorizationService>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationPolicyProvider, DefaultAuthorizationPolicyProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationEvaluator, DefaultAuthorizationEvaluator>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationHandlerContextFactory, DefaultAuthorizationHandlerContextFactory>());
|
||||
services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, PassThroughAuthorizationHandler>());
|
||||
return services;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authorization
|
||||
{
|
||||
/// <summary>
|
||||
/// A type used to provide a <see cref="AuthorizationHandlerContext"/> used for authorization.
|
||||
/// </summary>
|
||||
public class DefaultAuthorizationHandlerContextFactory : IAuthorizationHandlerContextFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a <see cref="AuthorizationHandlerContext"/> used for authorization.
|
||||
/// </summary>
|
||||
/// <param name="requirements">The requirements to evaluate.</param>
|
||||
/// <param name="user">The user to evaluate the requirements against.</param>
|
||||
/// <param name="resource">
|
||||
/// An optional resource the policy should be checked with.
|
||||
/// If a resource is not required for policy evaluation you may pass null as the value.
|
||||
/// </param>
|
||||
/// <returns>The <see cref="AuthorizationHandlerContext"/>.</returns>
|
||||
public virtual AuthorizationHandlerContext CreateContext(IEnumerable<IAuthorizationRequirement> requirements, ClaimsPrincipal user, object resource)
|
||||
{
|
||||
return new AuthorizationHandlerContext(requirements, user, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
/// </summary>
|
||||
public class DefaultAuthorizationService : IAuthorizationService
|
||||
{
|
||||
private readonly IAuthorizationHandlerContextFactory _contextFactory;
|
||||
private readonly IAuthorizationEvaluator _evaluator;
|
||||
private readonly IAuthorizationPolicyProvider _policyProvider;
|
||||
private readonly IList<IAuthorizationHandler> _handlers;
|
||||
|
|
@ -27,7 +28,7 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
/// <param name="policyProvider">The <see cref="IAuthorizationPolicyProvider"/> used to provide policies.</param>
|
||||
/// <param name="handlers">The handlers used to fulfill <see cref="IAuthorizationRequirement"/>s.</param>
|
||||
/// <param name="logger">The logger used to log messages, warnings and errors.</param>
|
||||
public DefaultAuthorizationService(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizationHandler> handlers, ILogger<DefaultAuthorizationService> logger) : this(policyProvider, handlers, logger, new DefaultAuthorizationEvaluator()) { }
|
||||
public DefaultAuthorizationService(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizationHandler> handlers, ILogger<DefaultAuthorizationService> logger) : this(policyProvider, handlers, logger, new DefaultAuthorizationHandlerContextFactory(), new DefaultAuthorizationEvaluator()) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DefaultAuthorizationService"/>.
|
||||
|
|
@ -35,8 +36,9 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
/// <param name="policyProvider">The <see cref="IAuthorizationPolicyProvider"/> used to provide policies.</param>
|
||||
/// <param name="handlers">The handlers used to fulfill <see cref="IAuthorizationRequirement"/>s.</param>
|
||||
/// <param name="logger">The logger used to log messages, warnings and errors.</param>
|
||||
/// <param name="contextFactory">The <see cref="IAuthorizationHandlerContextFactory"/> used to create the context to handle the authorization.</param>
|
||||
/// <param name="evaluator">The <see cref="IAuthorizationEvaluator"/> used to determine if authorzation was successful.</param>
|
||||
public DefaultAuthorizationService(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizationHandler> handlers, ILogger<DefaultAuthorizationService> logger, IAuthorizationEvaluator evaluator)
|
||||
public DefaultAuthorizationService(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizationHandler> handlers, ILogger<DefaultAuthorizationService> logger, IAuthorizationHandlerContextFactory contextFactory, IAuthorizationEvaluator evaluator)
|
||||
{
|
||||
if (policyProvider == null)
|
||||
{
|
||||
|
|
@ -50,6 +52,10 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
if (contextFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(contextFactory));
|
||||
}
|
||||
if (evaluator == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(evaluator));
|
||||
|
|
@ -59,6 +65,7 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
_policyProvider = policyProvider;
|
||||
_logger = logger;
|
||||
_evaluator = evaluator;
|
||||
_contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -78,7 +85,7 @@ namespace Microsoft.AspNetCore.Authorization
|
|||
throw new ArgumentNullException(nameof(requirements));
|
||||
}
|
||||
|
||||
var authContext = new AuthorizationHandlerContext(requirements, user, resource);
|
||||
var authContext = _contextFactory.CreateContext(requirements, user, resource);
|
||||
foreach (var handler in _handlers)
|
||||
{
|
||||
await handler.HandleAsync(authContext);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authorization
|
||||
{
|
||||
/// <summary>
|
||||
/// A type used to provide a <see cref="AuthorizationHandlerContext"/> used for authorization.
|
||||
/// </summary>
|
||||
public interface IAuthorizationHandlerContextFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a <see cref="AuthorizationHandlerContext"/> used for authorization.
|
||||
/// </summary>
|
||||
/// <param name="requirements">The requirements to evaluate.</param>
|
||||
/// <param name="user">The user to evaluate the requirements against.</param>
|
||||
/// <param name="resource">
|
||||
/// An optional resource the policy should be checked with.
|
||||
/// If a resource is not required for policy evaluation you may pass null as the value.
|
||||
/// </param>
|
||||
/// <returns>The <see cref="AuthorizationHandlerContext"/>.</returns>
|
||||
AuthorizationHandlerContext CreateContext(IEnumerable<IAuthorizationRequirement> requirements, ClaimsPrincipal user, object resource);
|
||||
}
|
||||
}
|
||||
|
|
@ -1038,11 +1038,52 @@ namespace Microsoft.AspNetCore.Authorization.Test
|
|||
{
|
||||
var authorizationService = BuildAuthorizationService(services =>
|
||||
{
|
||||
// This will ignore the policy options
|
||||
services.AddSingleton<IAuthorizationEvaluator, SuccessEvaluator>();
|
||||
services.AddAuthorization(options => options.AddPolicy("Fail", p => p.RequireAssertion(c => false)));
|
||||
});
|
||||
Assert.True(await authorizationService.AuthorizeAsync(null, "Fail"));
|
||||
}
|
||||
|
||||
|
||||
public class BadContextMaker : IAuthorizationHandlerContextFactory
|
||||
{
|
||||
public AuthorizationHandlerContext CreateContext(IEnumerable<IAuthorizationRequirement> requirements, ClaimsPrincipal user, object resource)
|
||||
{
|
||||
return new BadContext();
|
||||
}
|
||||
}
|
||||
|
||||
public class BadContext : AuthorizationHandlerContext
|
||||
{
|
||||
public BadContext() : base(new List<IAuthorizationRequirement>(), null, null) { }
|
||||
|
||||
public override bool HasFailed
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasSucceeded
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanUseCustomContextThatAlwaysFails()
|
||||
{
|
||||
var authorizationService = BuildAuthorizationService(services =>
|
||||
{
|
||||
services.AddSingleton<IAuthorizationHandlerContextFactory, BadContextMaker>();
|
||||
services.AddAuthorization(options => options.AddPolicy("Success", p => p.RequireAssertion(c => true)));
|
||||
});
|
||||
Assert.False(await authorizationService.AuthorizeAsync(null, "Success"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue