Async overloads for AuthZ RequireAssertion

This commit is contained in:
Hao Kung 2016-01-27 16:35:43 -08:00
parent a80c5e6d85
commit 80dc5759cc
3 changed files with 52 additions and 5 deletions

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization.Infrastructure; using Microsoft.AspNetCore.Authorization.Infrastructure;
namespace Microsoft.AspNetCore.Authorization namespace Microsoft.AspNetCore.Authorization
@ -139,6 +140,22 @@ namespace Microsoft.AspNetCore.Authorization
return this; return this;
} }
/// <summary>
/// Requires that this Function returns true
/// </summary>
/// <param name="assert">Function that must return true</param>
/// <returns></returns>
public AuthorizationPolicyBuilder RequireAssertion(Func<AuthorizationContext, Task<bool>> assert)
{
if (assert == null)
{
throw new ArgumentNullException(nameof(assert));
}
Requirements.Add(new AssertionRequirement(assert));
return this;
}
public AuthorizationPolicy Build() public AuthorizationPolicy Build()
{ {
return new AuthorizationPolicy(Requirements, AuthenticationSchemes.Distinct()); return new AuthorizationPolicy(Requirements, AuthenticationSchemes.Distinct());

View File

@ -2,15 +2,16 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure namespace Microsoft.AspNetCore.Authorization.Infrastructure
{ {
public class AssertionRequirement : AuthorizationHandler<AssertionRequirement>, IAuthorizationRequirement public class AssertionRequirement : IAuthorizationHandler, IAuthorizationRequirement
{ {
/// <summary> /// <summary>
/// Function that is called to handle this requirement /// Function that is called to handle this requirement
/// </summary> /// </summary>
public Func<AuthorizationContext, bool> Handler { get; } public Func<AuthorizationContext, Task<bool>> Handler { get; }
public AssertionRequirement(Func<AuthorizationContext, bool> assert) public AssertionRequirement(Func<AuthorizationContext, bool> assert)
{ {
@ -19,14 +20,24 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure
throw new ArgumentNullException(nameof(assert)); throw new ArgumentNullException(nameof(assert));
} }
Handler = context => Task.FromResult(assert(context));
}
public AssertionRequirement(Func<AuthorizationContext, Task<bool>> assert)
{
if (assert == null)
{
throw new ArgumentNullException(nameof(assert));
}
Handler = assert; Handler = assert;
} }
protected override void Handle(AuthorizationContext context, AssertionRequirement requirement) public async Task HandleAsync(AuthorizationContext context)
{ {
if (Handler(context)) if (await Handler(context))
{ {
context.Succeed(requirement); context.Succeed(this);
} }
} }
} }

View File

@ -923,6 +923,25 @@ namespace Microsoft.AspNetCore.Authorization.Test
Assert.True(allowed); Assert.True(allowed);
} }
[Fact]
public async Task CanAuthorizeWithAsyncAssertionRequirement()
{
var authorizationService = BuildAuthorizationService(services =>
{
services.AddAuthorization(options =>
{
options.AddPolicy("Basic", policy => policy.RequireAssertion(context => Task.FromResult(true)));
});
});
var user = new ClaimsPrincipal();
// Act
var allowed = await authorizationService.AuthorizeAsync(user, "Basic");
// Assert
Assert.True(allowed);
}
public class StaticPolicyProvider : IAuthorizationPolicyProvider public class StaticPolicyProvider : IAuthorizationPolicyProvider
{ {
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName) public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)