diff --git a/src/Microsoft.AspNetCore.Authorization/AuthorizationHandler.cs b/src/Microsoft.AspNetCore.Authorization/AuthorizationHandler.cs index f6877f114e..2eb19c6176 100644 --- a/src/Microsoft.AspNetCore.Authorization/AuthorizationHandler.cs +++ b/src/Microsoft.AspNetCore.Authorization/AuthorizationHandler.cs @@ -6,65 +6,63 @@ using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization { + /// + /// Base class for authorization handlers that need to be called for a specific requirement type. + /// + /// The type of the requirement to handle. public abstract class AuthorizationHandler : IAuthorizationHandler - where TRequirement : IAuthorizationRequirement + where TRequirement : IAuthorizationRequirement { - public void Handle(AuthorizationHandlerContext context) - { - foreach (var req in context.Requirements.OfType()) - { - Handle(context, req); - } - } - + /// + /// Makes a decision if authorization is allowed. + /// + /// The authorization information. public virtual async Task HandleAsync(AuthorizationHandlerContext context) { foreach (var req in context.Requirements.OfType()) { - await HandleAsync(context, req); + await HandleRequirementAsync(context, req); } } - protected abstract void Handle(AuthorizationHandlerContext context, TRequirement requirement); - - protected virtual Task HandleAsync(AuthorizationHandlerContext context, TRequirement requirement) - { - Handle(context, requirement); - return Task.FromResult(0); - } + /// + /// Makes a decision if authorization is allowed based on a specific requirement. + /// + /// The authorization information. + /// The requirement to evaluate. + protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement); } + /// + /// Base class for authorization handlers that need to be called for specific requirement and + /// resource types. + /// + /// The type of the requirement to evaluate. + /// The type of the resource to evaluate. public abstract class AuthorizationHandler : IAuthorizationHandler where TRequirement : IAuthorizationRequirement { + /// + /// Makes a decision if authorization is allowed. + /// + /// The authorization information. public virtual async Task HandleAsync(AuthorizationHandlerContext context) { if (context.Resource is TResource) { foreach (var req in context.Requirements.OfType()) { - await HandleAsync(context, req, (TResource)context.Resource); + await HandleRequirementAsync(context, req, (TResource)context.Resource); } } } - protected virtual Task HandleAsync(AuthorizationHandlerContext context, TRequirement requirement, TResource resource) - { - Handle(context, requirement, resource); - return Task.FromResult(0); - } - - public virtual void Handle(AuthorizationHandlerContext context) - { - if (context.Resource is TResource) - { - foreach (var req in context.Requirements.OfType()) - { - Handle(context, req, (TResource)context.Resource); - } - } - } - - protected abstract void Handle(AuthorizationHandlerContext context, TRequirement requirement, TResource resource); + /// + /// Makes a decision if authorization is allowed based on a specific requirement and resource. + /// + /// The authorization information. + /// The requirement to evaluate. + /// The resource to evaluate. + protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement, TResource resource); } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Authorization/IAuthorizationHandler.cs b/src/Microsoft.AspNetCore.Authorization/IAuthorizationHandler.cs index cf7896a30e..afe9e43f02 100644 --- a/src/Microsoft.AspNetCore.Authorization/IAuthorizationHandler.cs +++ b/src/Microsoft.AspNetCore.Authorization/IAuthorizationHandler.cs @@ -5,8 +5,15 @@ using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization { + /// + /// Classes implementing this interface are able to make a decision if authorization is allowed. + /// public interface IAuthorizationHandler { + /// + /// Makes a decision if authorization is allowed. + /// + /// The authorization information. Task HandleAsync(AuthorizationHandlerContext context); } } diff --git a/src/Microsoft.AspNetCore.Authorization/Infrastructure/ClaimsAuthorizationRequirement.cs b/src/Microsoft.AspNetCore.Authorization/Infrastructure/ClaimsAuthorizationRequirement.cs index 644b33086d..c5a06c2f95 100644 --- a/src/Microsoft.AspNetCore.Authorization/Infrastructure/ClaimsAuthorizationRequirement.cs +++ b/src/Microsoft.AspNetCore.Authorization/Infrastructure/ClaimsAuthorizationRequirement.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization.Infrastructure { @@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure public string ClaimType { get; } public IEnumerable AllowedValues { get; } - protected override void Handle(AuthorizationHandlerContext context, ClaimsAuthorizationRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ClaimsAuthorizationRequirement requirement) { if (context.User != null) { @@ -44,6 +45,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure context.Succeed(requirement); } } + return Task.FromResult(0); } } } diff --git a/src/Microsoft.AspNetCore.Authorization/Infrastructure/DenyAnonymousAuthorizationRequirement.cs b/src/Microsoft.AspNetCore.Authorization/Infrastructure/DenyAnonymousAuthorizationRequirement.cs index 57ad22dff6..82d40639bc 100644 --- a/src/Microsoft.AspNetCore.Authorization/Infrastructure/DenyAnonymousAuthorizationRequirement.cs +++ b/src/Microsoft.AspNetCore.Authorization/Infrastructure/DenyAnonymousAuthorizationRequirement.cs @@ -2,12 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; +using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization.Infrastructure { public class DenyAnonymousAuthorizationRequirement : AuthorizationHandler, IAuthorizationRequirement { - protected override void Handle(AuthorizationHandlerContext context, DenyAnonymousAuthorizationRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DenyAnonymousAuthorizationRequirement requirement) { var user = context.User; var userIsAnonymous = @@ -17,6 +18,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure { context.Succeed(requirement); } + return Task.FromResult(0); } } } diff --git a/src/Microsoft.AspNetCore.Authorization/Infrastructure/NameAuthorizationRequirement.cs b/src/Microsoft.AspNetCore.Authorization/Infrastructure/NameAuthorizationRequirement.cs index b0c4e6b101..3643b1fb7a 100644 --- a/src/Microsoft.AspNetCore.Authorization/Infrastructure/NameAuthorizationRequirement.cs +++ b/src/Microsoft.AspNetCore.Authorization/Infrastructure/NameAuthorizationRequirement.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization.Infrastructure { @@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure public string RequiredName { get; } - protected override void Handle(AuthorizationHandlerContext context, NameAuthorizationRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NameAuthorizationRequirement requirement) { if (context.User != null) { @@ -33,6 +34,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure context.Succeed(requirement); } } + return Task.FromResult(0); } } } diff --git a/src/Microsoft.AspNetCore.Authorization/Infrastructure/RolesAuthorizationRequirement.cs b/src/Microsoft.AspNetCore.Authorization/Infrastructure/RolesAuthorizationRequirement.cs index a57a0e4c8e..53d6beb167 100644 --- a/src/Microsoft.AspNetCore.Authorization/Infrastructure/RolesAuthorizationRequirement.cs +++ b/src/Microsoft.AspNetCore.Authorization/Infrastructure/RolesAuthorizationRequirement.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization.Infrastructure { @@ -27,7 +28,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure public IEnumerable AllowedRoles { get; } - protected override void Handle(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement) { if (context.User != null) { @@ -45,6 +46,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure context.Succeed(requirement); } } + return Task.FromResult(0); } } diff --git a/test/Microsoft.AspNetCore.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNetCore.Authorization.Test/DefaultAuthorizationServiceTests.cs index b6383ffb48..19bd761e05 100644 --- a/test/Microsoft.AspNetCore.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNetCore.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -584,9 +584,10 @@ namespace Microsoft.AspNetCore.Authorization.Test public class CustomRequirement : IAuthorizationRequirement { } public class CustomHandler : AuthorizationHandler { - protected override void Handle(AuthorizationHandlerContext context, CustomRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement) { context.Succeed(requirement); + return Task.FromResult(0); } } @@ -640,11 +641,12 @@ namespace Microsoft.AspNetCore.Authorization.Test public bool Succeed { get; set; } - protected override void Handle(AuthorizationHandlerContext context, PassThroughRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PassThroughRequirement requirement) { if (Succeed) { context.Succeed(requirement); } + return Task.FromResult(0); } } @@ -770,23 +772,25 @@ namespace Microsoft.AspNetCore.Authorization.Test private IEnumerable _allowed; - protected override void Handle(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, ExpenseReport resource) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, ExpenseReport resource) { if (_allowed.Contains(requirement)) { context.Succeed(requirement); } + return Task.FromResult(0); } } public class SuperUserHandler : AuthorizationHandler { - protected override void Handle(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement) { if (context.User.HasClaim("SuperUser", "yes")) { context.Succeed(requirement); } + return Task.FromResult(0); } } @@ -816,7 +820,7 @@ namespace Microsoft.AspNetCore.Authorization.Test public class NotCalledHandler : AuthorizationHandler { - protected override void Handle(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, string resource) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, string resource) { throw new NotImplementedException(); } @@ -824,12 +828,13 @@ namespace Microsoft.AspNetCore.Authorization.Test public class EvenHandler : AuthorizationHandler { - protected override void Handle(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, int id) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, int id) { if (id % 2 == 0) { context.Succeed(requirement); } + return Task.FromResult(0); } }