AuthZ: Combine needs to use policy provider

Fixes https://github.com/aspnet/Security/issues/841
This commit is contained in:
Hao Kung 2016-05-31 13:45:30 -07:00
parent 080447e9aa
commit c257c9528f
5 changed files with 61 additions and 24 deletions

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization
{
@ -57,27 +58,27 @@ namespace Microsoft.AspNetCore.Authorization
return builder.Build();
}
public static AuthorizationPolicy Combine(AuthorizationOptions options, IEnumerable<IAuthorizeData> attributes)
public static async Task<AuthorizationPolicy> CombineAsync(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizeData> authorizeData)
{
if (options == null)
if (policyProvider == null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(policyProvider));
}
if (attributes == null)
if (authorizeData == null)
{
throw new ArgumentNullException(nameof(attributes));
throw new ArgumentNullException(nameof(authorizeData));
}
var policyBuilder = new AuthorizationPolicyBuilder();
var any = false;
foreach (var authorizeAttribute in attributes.OfType<AuthorizeAttribute>())
foreach (var authorizeAttribute in authorizeData.OfType<AuthorizeAttribute>())
{
any = true;
var useDefaultPolicy = true;
if (!string.IsNullOrWhiteSpace(authorizeAttribute.Policy))
{
var policy = options.GetPolicy(authorizeAttribute.Policy);
var policy = await policyProvider.GetPolicyAsync(authorizeAttribute.Policy);
if (policy == null)
{
throw new InvalidOperationException(Resources.FormatException_AuthorizationPolicyNotFound(authorizeAttribute.Policy));
@ -89,7 +90,6 @@ namespace Microsoft.AspNetCore.Authorization
if (rolesSplit != null && rolesSplit.Any())
{
var trimmedRolesSplit = rolesSplit.Where(r => !string.IsNullOrWhiteSpace(r)).Select(r => r.Trim());
policyBuilder.RequireRole(trimmedRolesSplit);
useDefaultPolicy = false;
}
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Authorization
}
if (useDefaultPolicy)
{
policyBuilder.Combine(options.DefaultPolicy);
policyBuilder.Combine(await policyProvider.GetDefaultPolicyAsync());
}
}
return any ? policyBuilder.Build() : null;

View File

@ -22,7 +22,12 @@ namespace Microsoft.AspNetCore.Authorization
}
_options = options.Value;
}
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return Task.FromResult(_options.DefaultPolicy);
}
/// <summary>
/// Gets a <see cref="AuthorizationPolicy"/> from the given <paramref name="policyName"/>

View File

@ -16,5 +16,11 @@ namespace Microsoft.AspNetCore.Authorization
/// <param name="policyName"></param>
/// <returns></returns>
Task<AuthorizationPolicy> GetPolicyAsync(string policyName);
/// <summary>
/// Returns the default <see cref="AuthorizationPolicy"/>.
/// </summary>
/// <returns></returns>
Task<AuthorizationPolicy> GetDefaultPolicyAsync();
}
}

View File

@ -3,8 +3,10 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using Microsoft.Extensions.Options;
using Xunit;
namespace Microsoft.AspNetCore.Authroization.Test
@ -18,7 +20,7 @@ namespace Microsoft.AspNetCore.Authroization.Test
}
[Fact]
public void CanCombineAuthorizeAttributes()
public async Task CanCombineAuthorizeAttributes()
{
// Arrange
var attributes = new AuthorizeAttribute[] {
@ -31,8 +33,10 @@ namespace Microsoft.AspNetCore.Authroization.Test
options.AddPolicy("1", policy => policy.RequireClaim("1"));
options.AddPolicy("2", policy => policy.RequireClaim("2"));
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(options));
// Act
var combined = AuthorizationPolicy.Combine(options, attributes);
var combined = await AuthorizationPolicy.CombineAsync(provider, attributes);
// Assert
Assert.Equal(2, combined.AuthenticationSchemes.Count());
@ -45,7 +49,7 @@ namespace Microsoft.AspNetCore.Authroization.Test
}
[Fact]
public void CanReplaceDefaultPolicy()
public async Task CanReplaceDefaultPolicy()
{
// Arrange
var attributes = new AuthorizeAttribute[] {
@ -56,8 +60,10 @@ namespace Microsoft.AspNetCore.Authroization.Test
options.DefaultPolicy = new AuthorizationPolicyBuilder("default").RequireClaim("default").Build();
options.AddPolicy("2", policy => policy.RequireClaim("2"));
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(options));
// Act
var combined = AuthorizationPolicy.Combine(options, attributes);
var combined = await AuthorizationPolicy.CombineAsync(provider, attributes);
// Assert
Assert.Equal(2, combined.AuthenticationSchemes.Count());
@ -69,16 +75,17 @@ namespace Microsoft.AspNetCore.Authroization.Test
}
[Fact]
public void CombineMustTrimRoles()
public async Task CombineMustTrimRoles()
{
// Arrange
var attributes = new AuthorizeAttribute[] {
new AuthorizeAttribute() { Roles = "r1 , r2" }
};
var options = new AuthorizationOptions();
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(options));
// Act
var combined = AuthorizationPolicy.Combine(options, attributes);
var combined = await AuthorizationPolicy.CombineAsync(provider, attributes);
// Assert
Assert.True(combined.Requirements.Any(r => r is RolesAuthorizationRequirement));
@ -89,7 +96,7 @@ namespace Microsoft.AspNetCore.Authroization.Test
}
[Fact]
public void CombineMustTrimAuthenticationScheme()
public async Task CombineMustTrimAuthenticationScheme()
{
// Arrange
var attributes = new AuthorizeAttribute[] {
@ -97,8 +104,10 @@ namespace Microsoft.AspNetCore.Authroization.Test
};
var options = new AuthorizationOptions();
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(options));
// Act
var combined = AuthorizationPolicy.Combine(options, attributes);
var combined = await AuthorizationPolicy.CombineAsync(provider, attributes);
// Assert
Assert.Equal(2, combined.AuthenticationSchemes.Count());
@ -107,7 +116,7 @@ namespace Microsoft.AspNetCore.Authroization.Test
}
[Fact]
public void CombineMustIgnoreEmptyAuthenticationScheme()
public async Task CombineMustIgnoreEmptyAuthenticationScheme()
{
// Arrange
var attributes = new AuthorizeAttribute[] {
@ -115,8 +124,10 @@ namespace Microsoft.AspNetCore.Authroization.Test
};
var options = new AuthorizationOptions();
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(options));
// Act
var combined = AuthorizationPolicy.Combine(options, attributes);
var combined = await AuthorizationPolicy.CombineAsync(provider, attributes);
// Assert
Assert.Equal(2, combined.AuthenticationSchemes.Count());
@ -125,16 +136,17 @@ namespace Microsoft.AspNetCore.Authroization.Test
}
[Fact]
public void CombineMustIgnoreEmptyRoles()
public async Task CombineMustIgnoreEmptyRoles()
{
// Arrange
var attributes = new AuthorizeAttribute[] {
new AuthorizeAttribute() { Roles = "r1 , ,, , r2" }
};
var options = new AuthorizationOptions();
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(options));
// Act
var combined = AuthorizationPolicy.Combine(options, attributes);
var combined = await AuthorizationPolicy.CombineAsync(provider, attributes);
// Assert
Assert.True(combined.Requirements.Any(r => r is RolesAuthorizationRequirement));

View File

@ -8,6 +8,7 @@ using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Xunit;
namespace Microsoft.AspNetCore.Authorization.Test
@ -28,9 +29,12 @@ namespace Microsoft.AspNetCore.Authorization.Test
}
[Fact]
public void AuthorizeCombineThrowsOnUnknownPolicy()
public async Task AuthorizeCombineThrowsOnUnknownPolicy()
{
Assert.Throws<InvalidOperationException>(() => AuthorizationPolicy.Combine(new AuthorizationOptions(), new AuthorizeAttribute[] {
var provider = new DefaultAuthorizationPolicyProvider(Options.Create(new AuthorizationOptions()));
// Act
await Assert.ThrowsAsync<InvalidOperationException>(() => AuthorizationPolicy.CombineAsync(provider, new AuthorizeAttribute[] {
new AuthorizeAttribute { Policy = "Wut" }
}));
}
@ -944,6 +948,11 @@ namespace Microsoft.AspNetCore.Authorization.Test
public class StaticPolicyProvider : IAuthorizationPolicyProvider
{
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
@ -973,6 +982,11 @@ namespace Microsoft.AspNetCore.Authorization.Test
public class DynamicPolicyProvider : IAuthorizationPolicyProvider
{
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
return Task.FromResult(new AuthorizationPolicyBuilder().RequireClaim(policyName).Build());