Doc Comments

This commit is contained in:
Barry Dorrans 2016-06-09 16:15:09 -07:00
parent e1495f5f32
commit 38e89d498d
21 changed files with 399 additions and 69 deletions

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Makes a decision if authorization is allowed.
/// </summary>
/// <param name="context">The authorization information.</param>
/// <param name="context">The authorization context.</param>
public virtual async Task HandleAsync(AuthorizationHandlerContext context)
{
foreach (var req in context.Requirements.OfType<TRequirement>())
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Makes a decision if authorization is allowed based on a specific requirement.
/// </summary>
/// <param name="context">The authorization information.</param>
/// <param name="context">The authorization context.</param>
/// <param name="requirement">The requirement to evaluate.</param>
protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement);
}
@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Makes a decision if authorization is allowed.
/// </summary>
/// <param name="context">The authorization information.</param>
/// <param name="context">The authorization context.</param>
public virtual async Task HandleAsync(AuthorizationHandlerContext context)
{
if (context.Resource is TResource)
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Makes a decision if authorization is allowed based on a specific requirement and resource.
/// </summary>
/// <param name="context">The authorization information.</param>
/// <param name="context">The authorization context.</param>
/// <param name="requirement">The requirement to evaluate.</param>
/// <param name="resource">The resource to evaluate.</param>
protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement, TResource resource);

View File

@ -17,6 +17,12 @@ namespace Microsoft.AspNetCore.Authorization
private bool _failCalled;
private bool _succeedCalled;
/// <summary>
/// Creates a new instance of <see cref="AuthorizationHandlerContext"/>.
/// </summary>
/// <param name="requirements">A collection of all the <see cref="IAuthorizationRequirement"/> for the current authorization action.</param>
/// <param name="user">A <see cref="ClaimsPrincipal"/> representing the current user.</param>
/// <param name="resource">An optional resource to evaluate the <paramref name="requirements"/> against.</param>
public AuthorizationHandlerContext(
IEnumerable<IAuthorizationRequirement> requirements,
ClaimsPrincipal user,
@ -33,14 +39,34 @@ namespace Microsoft.AspNetCore.Authorization
_pendingRequirements = new HashSet<IAuthorizationRequirement>(requirements);
}
/// <summary>
/// The collection of all the <see cref="IAuthorizationRequirement"/> for the current authorization action.
/// </summary>
public IEnumerable<IAuthorizationRequirement> Requirements { get; }
/// <summary>
/// The <see cref="ClaimsPrincipal"/> representing the current user.
/// </summary>
public ClaimsPrincipal User { get; }
/// <summary>
/// The optional resource to evaluate the <see cref="AuthorizationHandlerContext.Requirements"/> against.
/// </summary>
public object Resource { get; }
/// <summary>
/// Gets the requirements that have not yet been succeeded.
/// </summary>
public IEnumerable<IAuthorizationRequirement> PendingRequirements { get { return _pendingRequirements; } }
/// <summary>
/// Flag indicating whether the current authorization processing has failed.
/// </summary>
public bool HasFailed { get { return _failCalled; } }
/// <summary>
/// Flag indicating whether the current authorization processing has succeeded.
/// </summary>
public bool HasSucceeded
{
get
@ -49,11 +75,20 @@ namespace Microsoft.AspNetCore.Authorization
}
}
/// <summary>
/// Called to indicate <see cref="AuthorizationHandlerContext.HasSucceeded"/> will
/// never return true, even if all requirements are met.
/// </summary>
public void Fail()
{
_failCalled = true;
}
/// <summary>
/// Called to mark the specified <paramref name="requirement"/> as being
/// successfully evaluated.
/// </summary>
/// <param name="requirement">The requirement whose evaluation has succeeded.</param>
public void Succeed(IAuthorizationRequirement requirement)
{
_succeedCalled = true;

View File

@ -14,8 +14,11 @@ namespace Microsoft.AspNetCore.Authorization
private IDictionary<string, AuthorizationPolicy> PolicyMap { get; } = new Dictionary<string, AuthorizationPolicy>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// The initial default policy is to require any authenticated user
/// Gets or sets the default authoization policy.
/// </summary>
/// <remarks>
/// The default policy is to require any authenticated user.
/// </remarks>
public AuthorizationPolicy DefaultPolicy { get; set; } = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
/// <summary>

View File

@ -8,8 +8,23 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// Represents a collection of authorization requirements and the scheme or
/// schemes they are evaluated against, all of which must succeed
/// for authorization to succeed.
/// </summary>
public class AuthorizationPolicy
{
/// <summary>
/// Creates a new instance of <see cref="AuthorizationPolicy"/>.
/// </summary>
/// <param name="requirements">
/// The list of <see cref="IAuthorizationRequirement"/>s which must succeed for
/// this policy to be successful.
/// </param>
/// <param name="authenticationSchemes">
/// The authentication schemes the <paramref name="requirements"/> are evaluated against.
/// </param>
public AuthorizationPolicy(IEnumerable<IAuthorizationRequirement> requirements, IEnumerable<string> authenticationSchemes)
{
if (requirements == null)
@ -30,9 +45,26 @@ namespace Microsoft.AspNetCore.Authorization
AuthenticationSchemes = new List<string>(authenticationSchemes).AsReadOnly();
}
/// <summary>
/// Gets a readonly list of <see cref="IAuthorizationRequirement"/>s which must succeed for
/// this policy to be successful.
/// </summary>
public IReadOnlyList<IAuthorizationRequirement> Requirements { get; }
/// <summary>
/// Gets a readonly list of rhe authentication schemes the <see cref="AuthorizationPolicy.Requirements"/>
/// are evaluated against.
/// </summary>
public IReadOnlyList<string> AuthenticationSchemes { get; }
/// <summary>
/// Combines the specified <see cref="AuthorizationPolicy"/> into a single policy.
/// </summary>
/// <param name="policies">The authorization policies to combine.</param>
/// <returns>
/// A new <see cref="AuthorizationPolicy"/> which represents the combination of the
/// specified <paramref name="policies"/>.
/// </returns>
public static AuthorizationPolicy Combine(params AuthorizationPolicy[] policies)
{
if (policies == null)
@ -43,6 +75,14 @@ namespace Microsoft.AspNetCore.Authorization
return Combine((IEnumerable<AuthorizationPolicy>)policies);
}
/// <summary>
/// Combines the specified <see cref="AuthorizationPolicy"/> into a single policy.
/// </summary>
/// <param name="policies">The authorization policies to combine.</param>
/// <returns>
/// A new <see cref="AuthorizationPolicy"/> which represents the combination of the
/// specified <paramref name="policies"/>.
/// </returns>
public static AuthorizationPolicy Combine(IEnumerable<AuthorizationPolicy> policies)
{
if (policies == null)
@ -58,6 +98,16 @@ namespace Microsoft.AspNetCore.Authorization
return builder.Build();
}
/// <summary>
/// Combines the <see cref="AuthorizationPolicy"/> provided by the specified
/// <paramref name="policyProvider"/>
/// </summary>
/// <param name="policyProvider">A <see cref="IAuthorizationPolicyProvider"/> which provides the policies to combine.</param>
/// <param name="authorizeData">A collection of authorization data used to apply authorization to a resource.</param>
/// <returns>
/// A new <see cref="AuthorizationPolicy"/> which represents the combination of the
/// authorization policies provided by specified <paramref name="policyProvider"/>.
/// </returns>
public static async Task<AuthorizationPolicy> CombineAsync(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizeData> authorizeData)
{
if (policyProvider == null)

View File

@ -9,21 +9,47 @@ using Microsoft.AspNetCore.Authorization.Infrastructure;
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// Used for building policies during application startup.
/// </summary>
public class AuthorizationPolicyBuilder
{
/// <summary>
/// Creates a new instance of <see cref="AuthorizationPolicyBuilder"/>
/// </summary>
/// <param name="authenticationSchemes">An array of authentication schemes the policy should be evaluated against.</param>
public AuthorizationPolicyBuilder(params string[] authenticationSchemes)
{
AddAuthenticationSchemes(authenticationSchemes);
}
/// <summary>
/// Creates a new instance of <see cref="AuthorizationPolicyBuilder"/>.
/// </summary>
/// <param name="policy">The <see cref="AuthorizationPolicy"/> to build.</param>
public AuthorizationPolicyBuilder(AuthorizationPolicy policy)
{
Combine(policy);
}
/// <summary>
/// Gets or sets a list of <see cref="IAuthorizationRequirement"/>s which must succeed for
/// this policy to be successful.
/// </summary>
public IList<IAuthorizationRequirement> Requirements { get; set; } = new List<IAuthorizationRequirement>();
/// <summary>
/// Gets or sets a list authentication schemes the <see cref="AuthorizationPolicyBuilder.Requirements"/>
/// are evaluated against.
/// </summary>
public IList<string> AuthenticationSchemes { get; set; } = new List<string>();
/// <summary>
/// Adds the specified authentication <paramref name="schemes"/> to the
/// <see cref="AuthorizationPolicyBuilder.AuthenticationSchemes"/> for this instance.
/// </summary>
/// <param name="schemes">The schemes to add.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder AddAuthenticationSchemes(params string[] schemes)
{
foreach (var authType in schemes)
@ -33,6 +59,12 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Adds the specified <paramref name="requirements"/> to the
/// <see cref="AuthorizationPolicyBuilder.Requirements"/> for this instance.
/// </summary>
/// <param name="requirements">The authorization requirements to add.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder AddRequirements(params IAuthorizationRequirement[] requirements)
{
foreach (var req in requirements)
@ -42,6 +74,11 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Combines the specified <paramref name="policy"/> into the current instance.
/// </summary>
/// <param name="policy">The <see cref="AuthorizationPolicy"/> to combine.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder Combine(AuthorizationPolicy policy)
{
if (policy == null)
@ -54,6 +91,13 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Adds a <see cref="ClaimsAuthorizationRequirement"/>
/// to the current instance.
/// </summary>
/// <param name="claimType">The claim type required.</param>
/// <param name="requiredValues">Values the claim must process one or more of for evaluation to succeed.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireClaim(string claimType, params string[] requiredValues)
{
if (claimType == null)
@ -64,6 +108,13 @@ namespace Microsoft.AspNetCore.Authorization
return RequireClaim(claimType, (IEnumerable<string>)requiredValues);
}
/// <summary>
/// Adds a <see cref="ClaimsAuthorizationRequirement"/>
/// to the current instance.
/// </summary>
/// <param name="claimType">The claim type required.</param>
/// <param name="requiredValues">Values the claim must process one or more of for evaluation to succeed.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireClaim(string claimType, IEnumerable<string> requiredValues)
{
if (claimType == null)
@ -75,6 +126,12 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Adds a <see cref="ClaimsAuthorizationRequirement"/>
/// to the current instance.
/// </summary>
/// <param name="claimType">The claim type required, which no restrictions on claim value.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireClaim(string claimType)
{
if (claimType == null)
@ -86,6 +143,12 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Adds a <see cref="RolesAuthorizationRequirement"/>
/// to the current instance.
/// </summary>
/// <param name="roles">The roles required.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireRole(params string[] roles)
{
if (roles == null)
@ -96,6 +159,12 @@ namespace Microsoft.AspNetCore.Authorization
return RequireRole((IEnumerable<string>)roles);
}
/// <summary>
/// Adds a <see cref="RolesAuthorizationRequirement"/>
/// to the current instance.
/// </summary>
/// <param name="roles">The roles required.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireRole(IEnumerable<string> roles)
{
if (roles == null)
@ -107,6 +176,12 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Adds a <see cref="NameAuthorizationRequirement"/>
/// to the current instance.
/// </summary>
/// <param name="userName">The user name the current user must possess.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireUserName(string userName)
{
if (userName == null)
@ -118,6 +193,10 @@ namespace Microsoft.AspNetCore.Authorization
return this;
}
/// <summary>
/// Adds a <see cref="DenyAnonymousAuthorizationRequirement"/> to the current instance.
/// </summary>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireAuthenticatedUser()
{
Requirements.Add(new DenyAnonymousAuthorizationRequirement());
@ -125,37 +204,44 @@ namespace Microsoft.AspNetCore.Authorization
}
/// <summary>
/// Requires that this Function returns true
/// Adds an <see cref="AssertionRequirement"/> to the current instance.
/// </summary>
/// <param name="assert">Function that must return true</param>
/// <returns></returns>
public AuthorizationPolicyBuilder RequireAssertion(Func<AuthorizationHandlerContext, bool> assert)
/// <param name="handler">The handler to evaluate during authorization.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireAssertion(Func<AuthorizationHandlerContext, bool> handler)
{
if (assert == null)
if (handler == null)
{
throw new ArgumentNullException(nameof(assert));
throw new ArgumentNullException(nameof(handler));
}
Requirements.Add(new AssertionRequirement(assert));
Requirements.Add(new AssertionRequirement(handler));
return this;
}
/// <summary>
/// Requires that this Function returns true
/// Adds an <see cref="AssertionRequirement"/> to the current instance.
/// </summary>
/// <param name="assert">Function that must return true</param>
/// <returns></returns>
public AuthorizationPolicyBuilder RequireAssertion(Func<AuthorizationHandlerContext, Task<bool>> assert)
/// <param name="handler">The handler to evaluate during authorization.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public AuthorizationPolicyBuilder RequireAssertion(Func<AuthorizationHandlerContext, Task<bool>> handler)
{
if (assert == null)
if (handler == null)
{
throw new ArgumentNullException(nameof(assert));
throw new ArgumentNullException(nameof(handler));
}
Requirements.Add(new AssertionRequirement(assert));
Requirements.Add(new AssertionRequirement(handler));
return this;
}
/// <summary>
/// Builds a new <see cref="AuthorizationPolicy"/> from the requirements
/// in this instance.
/// </summary>
/// <returns>
/// A new <see cref="AuthorizationPolicy"/> built from the requirements in this instance.
/// </returns>
public AuthorizationPolicy Build()
{
return new AuthorizationPolicy(Requirements, AuthenticationSchemes.Distinct());

View File

@ -8,16 +8,22 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// Extension methods for <see cref="IAuthorizationService"/>.
/// </summary>
public static class AuthorizationServiceExtensions
{
/// <summary>
/// Checks if a user meets a specific requirement for the specified resource
/// </summary>
/// <param name="service">The <see cref="IAuthorizationService"/>.</param>
/// <param name="user"></param>
/// <param name="resource"></param>
/// <param name="requirement"></param>
/// <returns></returns>
/// <param name="service">The <see cref="IAuthorizationService"/> providing authorization.</param>
/// <param name="user">The user to evaluate the policy against.</param>
/// <param name="resource">The resource to evaluate the policy against.</param>
/// <param name="requirement">The requirement to evaluate the policy against.</param>
/// <returns>
/// A flag indicating whether requirement evaluation has succeeded or failed.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
public static Task<bool> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, object resource, IAuthorizationRequirement requirement)
{
if (service == null)
@ -34,13 +40,16 @@ namespace Microsoft.AspNetCore.Authorization
}
/// <summary>
/// Checks if a user meets a specific authorization policy
/// Checks if a user meets a specific authorization policy against the specified resource.
/// </summary>
/// <param name="service">The authorization service.</param>
/// <param name="user">The user to check the policy against.</param>
/// <param name="resource">The resource the policy should be checked with.</param>
/// <param name="policy">The policy to check against a specific context.</param>
/// <returns><value>true</value> when the user fulfills the policy, <value>false</value> otherwise.</returns>
/// <param name="service">The <see cref="IAuthorizationService"/> providing authorization.</param>
/// <param name="user">The user to evaluate the policy against.</param>
/// <param name="resource">The resource to evaluate the policy against.</param>
/// <param name="policy">The policy to evaluate.</param>
/// <returns>
/// A flag indicating whether policy evaluation has succeeded or failed.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
public static Task<bool> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, object resource, AuthorizationPolicy policy)
{
if (service == null)
@ -57,12 +66,15 @@ namespace Microsoft.AspNetCore.Authorization
}
/// <summary>
/// Checks if a user meets a specific authorization policy
/// Checks if a user meets a specific authorization policy against the specified resource.
/// </summary>
/// <param name="service">The authorization service.</param>
/// <param name="user">The user to check the policy against.</param>
/// <param name="policy">The policy to check against a specific context.</param>
/// <returns><value>true</value> when the user fulfills the policy, <value>false</value> otherwise.</returns>
/// <param name="service">The <see cref="IAuthorizationService"/> providing authorization.</param>
/// <param name="user">The user to evaluate the policy against.</param>
/// <param name="policy">The policy to evaluate.</param>
/// <returns>
/// A flag indicating whether policy evaluation has succeeded or failed.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
public static Task<bool> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, AuthorizationPolicy policy)
{
if (service == null)
@ -79,12 +91,15 @@ namespace Microsoft.AspNetCore.Authorization
}
/// <summary>
/// Checks if a user meets a specific authorization policy
/// Checks if a user meets a specific authorization policy against the specified resource.
/// </summary>
/// <param name="service">The authorization service.</param>
/// <param name="user">The user to check the policy against.</param>
/// <param name="policyName">The name of the policy to check against a specific context.</param>
/// <returns><value>true</value> when the user fulfills the policy, <value>false</value> otherwise.</returns>
/// <param name="service">The <see cref="IAuthorizationService"/> providing authorization.</param>
/// <param name="user">The user to evaluate the policy against.</param>
/// <param name="policyName">The name of the policy to evaluate.</param>
/// <returns>
/// A flag indicating whether policy evaluation has succeeded or failed.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
public static Task<bool> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, string policyName)
{
if (service == null)

View File

@ -29,7 +29,6 @@ namespace Microsoft.AspNetCore.Authorization
public string Policy { get; set; }
/// <inheritdoc />
// REVIEW: can we get rid of the , deliminated in Roles/AuthTypes
public string Roles { get; set; }
/// <inheritdoc />

View File

@ -8,12 +8,17 @@ using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// A type which can provide a <see cref="AuthorizationPolicy"/> for a particular name.
/// The default implementation of a policy provider,
/// which provides a <see cref="AuthorizationPolicy"/> for a particular name.
/// </summary>
public class DefaultAuthorizationPolicyProvider : IAuthorizationPolicyProvider
{
private readonly AuthorizationOptions _options;
/// <summary>
/// Creates a new instance of <see cref="DefaultAuthorizationPolicyProvider"/>.
/// </summary>
/// <param name="options">The options used to configure this instance.</param>
public DefaultAuthorizationPolicyProvider(IOptions<AuthorizationOptions> options)
{
if (options == null)
@ -24,6 +29,10 @@ namespace Microsoft.AspNetCore.Authorization
_options = options.Value;
}
/// <summary>
/// Gets the default authorization policy.
/// </summary>
/// <returns>The default authorization policy.</returns>
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return Task.FromResult(_options.DefaultPolicy);
@ -32,8 +41,8 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Gets a <see cref="AuthorizationPolicy"/> from the given <paramref name="policyName"/>
/// </summary>
/// <param name="policyName"></param>
/// <returns></returns>
/// <param name="policyName">The policy name to retrieve.</param>
/// <returns>The named <see cref="AuthorizationPolicy"/>.</returns>
public virtual Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
return Task.FromResult(_options.GetPolicy(policyName));

View File

@ -11,12 +11,21 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// The default implementation of an <see cref="IAuthorizationService"/>.
/// </summary>
public class DefaultAuthorizationService : IAuthorizationService
{
private readonly IAuthorizationPolicyProvider _policyProvider;
private readonly IList<IAuthorizationHandler> _handlers;
private readonly ILogger _logger;
/// <summary>
/// Creates a new instance of <see cref="DefaultAuthorizationService"/>.
/// </summary>
/// <param name="policyProvider">The <see cref="IAuthorizationPolicyProvider"/> used to provide policies.</param>
/// <param name="handlers">The handlers used to fufills <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)
{
if (policyProvider == null)
@ -37,6 +46,16 @@ namespace Microsoft.AspNetCore.Authorization
_logger = logger;
}
/// <summary>
/// Checks if a user meets a specific set of requirements for the specified resource
/// </summary>
/// <param name="user">The user to evaluate the requirements against.</param>
/// <param name="resource">The resource to evaluate the requirements against.</param>
/// <param name="requirements">The requirements to evaluate.</param>
/// <returns>
/// A flag indicating whether authorization has succeded.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
public async Task<bool> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements)
{
if (requirements == null)
@ -84,6 +103,16 @@ namespace Microsoft.AspNetCore.Authorization
return (identity as ClaimsIdentity)?.FindFirst(claimsType)?.Value;
}
/// <summary>
/// Checks if a user meets a specific authorization policy
/// </summary>
/// <param name="user">The user to check the policy against.</param>
/// <param name="resource">The resource the policy should be checked with.</param>
/// <param name="policyName">The name of the policy to check against a specific context.</param>
/// <returns>
/// A flag indicating whether authorization has succeded.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
public async Task<bool> AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName)
{
if (policyName == null)

View File

@ -3,6 +3,9 @@
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// Marker interface to enable the <see cref="AllowAnonymousAttribute"/>.
/// </summary>
public interface IAllowAnonymous
{
}

View File

@ -13,14 +13,14 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Gets a <see cref="AuthorizationPolicy"/> from the given <paramref name="policyName"/>
/// </summary>
/// <param name="policyName"></param>
/// <returns></returns>
/// <param name="policyName">The policy name to retrieve.</param>
/// <returns>The named <see cref="AuthorizationPolicy"/>.</returns>
Task<AuthorizationPolicy> GetPolicyAsync(string policyName);
/// <summary>
/// Returns the default <see cref="AuthorizationPolicy"/>.
/// Gets the default authorization policy.
/// </summary>
/// <returns></returns>
/// <returns>The default authorization policy.</returns>
Task<AuthorizationPolicy> GetDefaultPolicyAsync();
}
}

View File

@ -3,6 +3,9 @@
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// Represents an authorization requirement.
/// </summary>
public interface IAuthorizationRequirement
{
}

View File

@ -15,10 +15,13 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Checks if a user meets a specific set of requirements for the specified resource
/// </summary>
/// <param name="user"></param>
/// <param name="resource"></param>
/// <param name="requirements"></param>
/// <returns></returns>
/// <param name="user">The user to evaluate the requirements against.</param>
/// <param name="resource">The resource to evaluate the requirements against.</param>
/// <param name="requirements">The requirements to evaluate.</param>
/// <returns>
/// A flag indicating whether authorization has succeded.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
Task<bool> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements);
/// <summary>
@ -27,7 +30,10 @@ namespace Microsoft.AspNetCore.Authorization
/// <param name="user">The user to check the policy against.</param>
/// <param name="resource">The resource the policy should be checked with.</param>
/// <param name="policyName">The name of the policy to check against a specific context.</param>
/// <returns><value>true</value> when the user fulfills the policy, <value>false</value> otherwise.</returns>
/// <returns>
/// A flag indicating whether authorization has succeded.
/// This value is <value>true</value> when the user fulfills the policy otherwise <value>false</value>.
/// </returns>
Task<bool> AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName);
}
}

View File

@ -14,10 +14,13 @@ namespace Microsoft.AspNetCore.Authorization
string Policy { get; set; }
/// <summary>
/// Gets or sets a comma-separated list of roles that are allowed to access the resource.
/// Gets or sets a comma delimited list of roles that are allowed to access the resource.
/// </summary>
string Roles { get; set; }
/// <summary>
/// Gets or sets a comma delimited list of schemes from which user information is constructed.
/// </summary>
string ActiveAuthenticationSchemes { get; set; }
}
}

View File

@ -6,33 +6,49 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
/// <summary>
/// Implements an <see cref="IAuthorizationHandler"/> and <see cref="IAuthorizationRequirement"/>
/// that takes an user specified assertion.
/// </summary>
public class AssertionRequirement : IAuthorizationHandler, IAuthorizationRequirement
{
/// <summary>
/// Function that is called to handle this requirement
/// Function that is called to handle this requirement.
/// </summary>
public Func<AuthorizationHandlerContext, Task<bool>> Handler { get; }
public AssertionRequirement(Func<AuthorizationHandlerContext, bool> assert)
/// <summary>
/// Creates a new instance of <see cref="AssertionRequirement"/>.
/// </summary>
/// <param name="handler">Function that is called to handle this requirement.</param>
public AssertionRequirement(Func<AuthorizationHandlerContext, bool> handler)
{
if (assert == null)
if (handler == null)
{
throw new ArgumentNullException(nameof(assert));
throw new ArgumentNullException(nameof(handler));
}
Handler = context => Task.FromResult(assert(context));
Handler = context => Task.FromResult(handler(context));
}
public AssertionRequirement(Func<AuthorizationHandlerContext, Task<bool>> assert)
/// <summary>
/// Creates a new instance of <see cref="AssertionRequirement"/>.
/// </summary>
/// <param name="handler">Function that is called to handle this requirement.</param>
public AssertionRequirement(Func<AuthorizationHandlerContext, Task<bool>> handler)
{
if (assert == null)
if (handler == null)
{
throw new ArgumentNullException(nameof(assert));
throw new ArgumentNullException(nameof(handler));
}
Handler = assert;
Handler = handler;
}
/// <summary>
/// Calls <see cref="AssertionRequirement.Handler"/> to see if authorization is allowed.
/// </summary>
/// <param name="context">The authorization information.</param>
public async Task HandleAsync(AuthorizationHandlerContext context)
{
if (await Handler(context))

View File

@ -8,10 +8,19 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
// Must contain a claim with the specified name, and at least one of the required values
// If AllowedValues is null or empty, that means any claim is valid
/// <summary>
/// Implements an <see cref="IAuthorizationHandler"/> and <see cref="IAuthorizationRequirement"/>
/// which requires at least one instance of the specified claim type, and, if allowed values are specified,
/// the claim value must be any of the allowed values.
/// </summary>
public class ClaimsAuthorizationRequirement : AuthorizationHandler<ClaimsAuthorizationRequirement>, IAuthorizationRequirement
{
/// <summary>
/// Creates a new instance of <see cref="ClaimsAuthorizationRequirement"/>.
/// </summary>
/// <param name="claimType">The claim type that must be present.</param>
/// <param name="allowedValues">The optional list of claim values, which, if present,
/// the claim must match.</param>
public ClaimsAuthorizationRequirement(string claimType, IEnumerable<string> allowedValues)
{
if (claimType == null)
@ -23,9 +32,22 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure
AllowedValues = allowedValues;
}
/// <summary>
/// Gets the claim type that must be present.
/// </summary>
public string ClaimType { get; }
/// <summary>
/// Gets the optional list of claim values, which, if present,
/// the claim must match.
/// </summary>
public IEnumerable<string> AllowedValues { get; }
/// <summary>
/// Makes a decision if authorization is allowed based on the claims requirements specified.
/// </summary>
/// <param name="context">The authorization context.</param>
/// <param name="requirement">The requirement to evaluate.</param>
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ClaimsAuthorizationRequirement requirement)
{
if (context.User != null)

View File

@ -6,8 +6,17 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
/// <summary>
/// Implements an <see cref="IAuthorizationHandler"/> and <see cref="IAuthorizationRequirement"/>
/// which requires the current user must be authenticated.
/// </summary>
public class DenyAnonymousAuthorizationRequirement : AuthorizationHandler<DenyAnonymousAuthorizationRequirement>, IAuthorizationRequirement
{
/// <summary>
/// Makes a decision if authorization is allowed based on a specific requirement.
/// </summary>
/// <param name="context">The authorization context.</param>
/// <param name="requirement">The requirement to evaluate.</param>
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DenyAnonymousAuthorizationRequirement requirement)
{
var user = context.User;

View File

@ -8,10 +8,15 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
/// <summary>
/// Requirement that ensures a specific Name
/// Implements an <see cref="IAuthorizationHandler"/> and <see cref="IAuthorizationRequirement"/>
/// which requires the current user name must match the specified value.
/// </summary>
public class NameAuthorizationRequirement : AuthorizationHandler<NameAuthorizationRequirement>, IAuthorizationRequirement
{
/// <summary>
/// Constructs a new instance of <see cref="NameAuthorizationRequirement"/>.
/// </summary>
/// <param name="requiredName">The required name that the current user must have.</param>
public NameAuthorizationRequirement(string requiredName)
{
if (requiredName == null)
@ -22,13 +27,20 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure
RequiredName = requiredName;
}
/// <summary>
/// Gets the required name that the current user must have.
/// </summary>
public string RequiredName { get; }
/// <summary>
/// Makes a decision if authorization is allowed based on a specific requirement.
/// </summary>
/// <param name="context">The authorization context.</param>
/// <param name="requirement">The requirement to evaluate.</param>
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NameAuthorizationRequirement requirement)
{
if (context.User != null)
{
// REVIEW: Do we need to do normalization? casing/loc?
if (context.User.Identities.Any(i => string.Equals(i.Name, requirement.RequiredName)))
{
context.Succeed(requirement);

View File

@ -3,8 +3,15 @@
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
/// <summary>
/// A helper class to provide a useful <see cref="IAuthorizationRequirement"/> which
/// contains a name.
/// </summary>
public class OperationAuthorizationRequirement : IAuthorizationRequirement
{
/// <summary>
/// The name of this instance of <see cref="IAuthorizationRequirement"/>.
/// </summary>
public string Name { get; set; }
}
}

View File

@ -6,8 +6,16 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
/// <summary>
/// Infrastructre class which allows an <see cref="IAuthorizationRequirement"/> to
/// be its own <see cref="IAuthorizationHandler"/>.
/// </summary>
public class PassThroughAuthorizationHandler : IAuthorizationHandler
{
/// <summary>
/// Makes a decision if authorization is allowed.
/// </summary>
/// <param name="context">The authorization context.</param>
public async Task HandleAsync(AuthorizationHandlerContext context)
{
foreach (var handler in context.Requirements.OfType<IAuthorizationHandler>())

View File

@ -8,10 +8,16 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authorization.Infrastructure
{
// Must belong to with one of specified roles
// If AllowedRoles is null or empty, that means any role is valid
/// <summary>
/// Implements an <see cref="IAuthorizationHandler"/> and <see cref="IAuthorizationRequirement"/>
/// which requires at least one role claim whose value must be any of the allowed roles.
/// </summary>
public class RolesAuthorizationRequirement : AuthorizationHandler<RolesAuthorizationRequirement>, IAuthorizationRequirement
{
/// <summary>
/// Creates a new instance of <see cref="RolesAuthorizationRequirement"/>.
/// </summary>
/// <param name="allowedRoles">A collection of allowed roles.</param>
public RolesAuthorizationRequirement(IEnumerable<string> allowedRoles)
{
if (allowedRoles == null)
@ -26,8 +32,17 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure
AllowedRoles = allowedRoles;
}
/// <summary>
/// Gets the collection of allowed roles.
/// </summary>
public IEnumerable<string> AllowedRoles { get; }
/// <summary>
/// Makes a decision if authorization is allowed based on a specific requirement.
/// </summary>
/// <param name="context">The authorization context.</param>
/// <param name="requirement">The requirement to evaluate.</param>
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement)
{
if (context.User != null)