Add IAuthorizationPolicyProvider support
This commit is contained in:
parent
9c41eb958e
commit
00ceeb0262
|
|
@ -26,6 +26,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationService, DefaultAuthorizationService>());
|
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationService, DefaultAuthorizationService>());
|
||||||
|
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationPolicyProvider, DefaultAuthorizationPolicyProvider>());
|
||||||
services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, PassThroughAuthorizationHandler>());
|
services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, PassThroughAuthorizationHandler>());
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// 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;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Authorization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A type which can provide a <see cref="AuthorizationPolicy"/> for a particular name.
|
||||||
|
/// </summary>
|
||||||
|
public class DefaultAuthorizationPolicyProvider : IAuthorizationPolicyProvider
|
||||||
|
{
|
||||||
|
private readonly AuthorizationOptions _options;
|
||||||
|
|
||||||
|
public DefaultAuthorizationPolicyProvider(IOptions<AuthorizationOptions> options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
_options = options.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="AuthorizationPolicy"/> from the given <paramref name="policyName"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="policyName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
|
||||||
|
{
|
||||||
|
return Task.FromResult(_options.GetPolicy(policyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,21 +7,20 @@ using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Authorization
|
namespace Microsoft.AspNetCore.Authorization
|
||||||
{
|
{
|
||||||
public class DefaultAuthorizationService : IAuthorizationService
|
public class DefaultAuthorizationService : IAuthorizationService
|
||||||
{
|
{
|
||||||
|
private readonly IAuthorizationPolicyProvider _policyProvider;
|
||||||
private readonly IList<IAuthorizationHandler> _handlers;
|
private readonly IList<IAuthorizationHandler> _handlers;
|
||||||
private readonly AuthorizationOptions _options;
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public DefaultAuthorizationService(IOptions<AuthorizationOptions> options, IEnumerable<IAuthorizationHandler> handlers, ILogger<DefaultAuthorizationService> logger)
|
public DefaultAuthorizationService(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizationHandler> handlers, ILogger<DefaultAuthorizationService> logger)
|
||||||
{
|
{
|
||||||
if (options == null)
|
if (policyProvider == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(options));
|
throw new ArgumentNullException(nameof(policyProvider));
|
||||||
}
|
}
|
||||||
if (handlers == null)
|
if (handlers == null)
|
||||||
{
|
{
|
||||||
|
|
@ -33,7 +32,7 @@ namespace Microsoft.AspNetCore.Authorization
|
||||||
}
|
}
|
||||||
|
|
||||||
_handlers = handlers.ToArray();
|
_handlers = handlers.ToArray();
|
||||||
_options = options.Value;
|
_policyProvider = policyProvider;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,19 +61,19 @@ namespace Microsoft.AspNetCore.Authorization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName)
|
public async Task<bool> AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName)
|
||||||
{
|
{
|
||||||
if (policyName == null)
|
if (policyName == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(policyName));
|
throw new ArgumentNullException(nameof(policyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
var policy = _options.GetPolicy(policyName);
|
var policy = await _policyProvider.GetPolicyAsync(policyName);
|
||||||
if (policy == null)
|
if (policy == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"No policy found: {policyName}.");
|
throw new InvalidOperationException($"No policy found: {policyName}.");
|
||||||
}
|
}
|
||||||
return this.AuthorizeAsync(user, resource, policy);
|
return await this.AuthorizeAsync(user, resource, policy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// 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.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Authorization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A type which can provide a <see cref="AuthorizationPolicy"/> for a particular name.
|
||||||
|
/// </summary>
|
||||||
|
public interface IAuthorizationPolicyProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="AuthorizationPolicy"/> from the given <paramref name="policyName"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="policyName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<AuthorizationPolicy> GetPolicyAsync(string policyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -922,5 +922,64 @@ namespace Microsoft.AspNetCore.Authorization.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(allowed);
|
Assert.True(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class StaticPolicyProvider : IAuthorizationPolicyProvider
|
||||||
|
{
|
||||||
|
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
|
||||||
|
{
|
||||||
|
return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanReplaceDefaultPolicyProvider()
|
||||||
|
{
|
||||||
|
var authorizationService = BuildAuthorizationService(services =>
|
||||||
|
{
|
||||||
|
// This will ignore the policy options
|
||||||
|
services.AddSingleton<IAuthorizationPolicyProvider, StaticPolicyProvider>();
|
||||||
|
services.AddAuthorization(options =>
|
||||||
|
{
|
||||||
|
options.AddPolicy("Basic", policy => policy.RequireAssertion(context => true));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var user = new ClaimsPrincipal();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var allowed = await authorizationService.AuthorizeAsync(user, "Basic");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(allowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DynamicPolicyProvider : IAuthorizationPolicyProvider
|
||||||
|
{
|
||||||
|
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
|
||||||
|
{
|
||||||
|
return Task.FromResult(new AuthorizationPolicyBuilder().RequireClaim(policyName).Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanUseDynamicPolicyProvider()
|
||||||
|
{
|
||||||
|
var authorizationService = BuildAuthorizationService(services =>
|
||||||
|
{
|
||||||
|
// This will ignore the policy options
|
||||||
|
services.AddSingleton<IAuthorizationPolicyProvider, DynamicPolicyProvider>();
|
||||||
|
services.AddAuthorization(options => { });
|
||||||
|
});
|
||||||
|
var id = new ClaimsIdentity();
|
||||||
|
id.AddClaim(new Claim("1", "1"));
|
||||||
|
id.AddClaim(new Claim("2", "2"));
|
||||||
|
var user = new ClaimsPrincipal(id);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
Assert.False(await authorizationService.AuthorizeAsync(user, "0"));
|
||||||
|
Assert.True(await authorizationService.AuthorizeAsync(user, "1"));
|
||||||
|
Assert.True(await authorizationService.AuthorizeAsync(user, "2"));
|
||||||
|
Assert.False(await authorizationService.AuthorizeAsync(user, "3"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNetCore.Authorization": "1.0.0-*",
|
"Microsoft.AspNetCore.Authorization": "1.0.0-*",
|
||||||
|
"Microsoft.AspNetCore.Testing": "1.0.0-*",
|
||||||
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
|
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
|
||||||
"Microsoft.Extensions.Logging": "1.0.0-*",
|
"Microsoft.Extensions.Logging": "1.0.0-*",
|
||||||
"xunit": "2.1.0"
|
"xunit": "2.1.0"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue