React to Authorize changes
This commit is contained in:
parent
3d30fd653e
commit
94ef6cf8fa
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
using MvcSample.Web.Filters;
|
using MvcSample.Web.Filters;
|
||||||
using MvcSample.Web.Models;
|
using MvcSample.Web.Models;
|
||||||
|
|
||||||
|
|
@ -50,14 +51,12 @@ namespace MvcSample.Web
|
||||||
return new ChallengeResult();
|
return new ChallengeResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize("CanViewPage")]
|
|
||||||
public ActionResult NotGrantedClaim(int age = 20, string userName = "SampleUser")
|
public ActionResult NotGrantedClaim(int age = 20, string userName = "SampleUser")
|
||||||
{
|
{
|
||||||
return Index(age, userName);
|
return Index(age, userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[FakeUser]
|
[FakeUser]
|
||||||
[Authorize("CanViewAnything")]
|
|
||||||
public ActionResult AllGranted(int age = 20, string userName = "SampleUser")
|
public ActionResult AllGranted(int age = 20, string userName = "SampleUser")
|
||||||
{
|
{
|
||||||
return Index(age, userName);
|
return Index(age, userName);
|
||||||
|
|
|
||||||
|
|
@ -40,19 +40,6 @@ namespace MvcSample.Web
|
||||||
|
|
||||||
app.UseServices(services =>
|
app.UseServices(services =>
|
||||||
{
|
{
|
||||||
services.ConfigureAuthorization(auth =>
|
|
||||||
{
|
|
||||||
auth.AddPolicy("CanViewPage",
|
|
||||||
new AuthorizationPolicyBuilder()
|
|
||||||
.RequiresClaim("Permission", "CanViewPage", "CanViewAnything").Build());
|
|
||||||
auth.AddPolicy("CanViewAnything",
|
|
||||||
new AuthorizationPolicyBuilder()
|
|
||||||
.RequiresClaim("Permission", "CanViewAnything").Build());
|
|
||||||
// This policy basically requires that the auth type is present
|
|
||||||
var basicPolicy = new AuthorizationPolicyBuilder("Basic").RequiresClaim(ClaimTypes.NameIdentifier);
|
|
||||||
auth.AddPolicy("RequireBasic", basicPolicy.Build());
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddMvc();
|
services.AddMvc();
|
||||||
services.AddSingleton<PassThroughAttribute>();
|
services.AddSingleton<PassThroughAttribute>();
|
||||||
services.AddSingleton<UserNameService>();
|
services.AddSingleton<UserNameService>();
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ using System.Reflection;
|
||||||
using Microsoft.AspNet.Mvc.Description;
|
using Microsoft.AspNet.Mvc.Description;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Routing;
|
using Microsoft.AspNet.Mvc.Routing;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
|
|
@ -16,6 +18,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DefaultActionModelBuilder : IActionModelBuilder
|
public class DefaultActionModelBuilder : IActionModelBuilder
|
||||||
{
|
{
|
||||||
|
private readonly AuthorizationOptions _authorizationOptions;
|
||||||
|
|
||||||
|
public DefaultActionModelBuilder(IOptions<AuthorizationOptions> options)
|
||||||
|
{
|
||||||
|
_authorizationOptions = options?.Options ?? new AuthorizationOptions();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerable<ActionModel> BuildActionModels([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo)
|
public IEnumerable<ActionModel> BuildActionModels([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo)
|
||||||
{
|
{
|
||||||
|
|
@ -256,6 +265,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
AddRange(actionModel.ActionConstraints, attributes.OfType<IActionConstraintMetadata>());
|
AddRange(actionModel.ActionConstraints, attributes.OfType<IActionConstraintMetadata>());
|
||||||
AddRange(actionModel.Filters, attributes.OfType<IFilter>());
|
AddRange(actionModel.Filters, attributes.OfType<IFilter>());
|
||||||
|
|
||||||
|
var policy = AuthorizationPolicy.Combine(_authorizationOptions, attributes.OfType<AuthorizeAttribute>());
|
||||||
|
if (policy != null)
|
||||||
|
{
|
||||||
|
actionModel.Filters.Add(new AuthorizeFilter(policy));
|
||||||
|
}
|
||||||
|
|
||||||
var actionName = attributes.OfType<ActionNameAttribute>().FirstOrDefault();
|
var actionName = attributes.OfType<ActionNameAttribute>().FirstOrDefault();
|
||||||
if (actionName?.Name != null)
|
if (actionName?.Name != null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ using System.Reflection;
|
||||||
using Microsoft.AspNet.Mvc.Description;
|
using Microsoft.AspNet.Mvc.Description;
|
||||||
using Microsoft.AspNet.Mvc.Filters;
|
using Microsoft.AspNet.Mvc.Filters;
|
||||||
using Microsoft.AspNet.Mvc.Routing;
|
using Microsoft.AspNet.Mvc.Routing;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
|
|
@ -19,15 +21,20 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
private readonly IActionModelBuilder _actionModelBuilder;
|
private readonly IActionModelBuilder _actionModelBuilder;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly AuthorizationOptions _authorizationOptions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="DefaultControllerModelBuilder"/>.
|
/// Creates a new <see cref="DefaultControllerModelBuilder"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actionModelBuilder">The <see cref="IActionModelBuilder"/> used to create actions.</param>
|
/// <param name="actionModelBuilder">The <see cref="IActionModelBuilder"/> used to create actions.</param>
|
||||||
public DefaultControllerModelBuilder(IActionModelBuilder actionModelBuilder, ILoggerFactory loggerFactory)
|
public DefaultControllerModelBuilder(
|
||||||
|
IActionModelBuilder actionModelBuilder,
|
||||||
|
ILoggerFactory loggerFactory,
|
||||||
|
IOptions<AuthorizationOptions> options)
|
||||||
{
|
{
|
||||||
_actionModelBuilder = actionModelBuilder;
|
_actionModelBuilder = actionModelBuilder;
|
||||||
_logger = loggerFactory.Create<DefaultControllerModelBuilder>();
|
_logger = loggerFactory.Create<DefaultControllerModelBuilder>();
|
||||||
|
_authorizationOptions = options?.Options ?? new AuthorizationOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -72,6 +79,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
AddRange(controllerModel.Filters, attributes.OfType<IFilter>());
|
AddRange(controllerModel.Filters, attributes.OfType<IFilter>());
|
||||||
AddRange(controllerModel.RouteConstraints, attributes.OfType<IRouteConstraintProvider>());
|
AddRange(controllerModel.RouteConstraints, attributes.OfType<IRouteConstraintProvider>());
|
||||||
|
|
||||||
|
var policy = AuthorizationPolicy.Combine(_authorizationOptions, attributes.OfType<AuthorizeAttribute>());
|
||||||
|
if (policy != null)
|
||||||
|
{
|
||||||
|
controllerModel.Filters.Add(new AuthorizeFilter(policy));
|
||||||
|
}
|
||||||
|
|
||||||
AddRange(
|
AddRange(
|
||||||
controllerModel.AttributeRoutes,
|
controllerModel.AttributeRoutes,
|
||||||
attributes.OfType<IRouteTemplateProvider>().Select(rtp => new AttributeRouteModel(rtp)));
|
attributes.OfType<IRouteTemplateProvider>().Select(rtp => new AttributeRouteModel(rtp)));
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. 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.AspNet.Mvc.Core;
|
|
||||||
using Microsoft.AspNet.Security;
|
|
||||||
using Microsoft.Framework.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
|
||||||
{
|
|
||||||
public class AuthorizeAttribute : AuthorizationFilterAttribute
|
|
||||||
{
|
|
||||||
private string _roles;
|
|
||||||
private string[] _rolesSplit;
|
|
||||||
|
|
||||||
public AuthorizeAttribute() { }
|
|
||||||
|
|
||||||
public AuthorizeAttribute(string policy)
|
|
||||||
{
|
|
||||||
Policy = policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Policy { get; set; }
|
|
||||||
|
|
||||||
public string Roles
|
|
||||||
{
|
|
||||||
get { return _roles; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_roles = value;
|
|
||||||
if (string.IsNullOrWhiteSpace(_roles))
|
|
||||||
{
|
|
||||||
_rolesSplit = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_rolesSplit = _roles.Split(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task OnAuthorizationAsync([NotNull] AuthorizationContext context)
|
|
||||||
{
|
|
||||||
var httpContext = context.HttpContext;
|
|
||||||
|
|
||||||
// Allow Anonymous skips all authorization
|
|
||||||
if (HasAllowAnonymous(context))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
|
|
||||||
|
|
||||||
// Build a policy for the requested roles if specified
|
|
||||||
if (_rolesSplit != null)
|
|
||||||
{
|
|
||||||
var rolesPolicy = new AuthorizationPolicyBuilder();
|
|
||||||
rolesPolicy.RequiresRole(_rolesSplit);
|
|
||||||
if (!await authService.AuthorizeAsync(rolesPolicy.Build(), httpContext, context))
|
|
||||||
{
|
|
||||||
Fail(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var authorized = (Policy == null)
|
|
||||||
// [Authorize] with no policy just requires any authenticated user
|
|
||||||
? await authService.AuthorizeAsync(BuildAnyAuthorizedUserPolicy(), httpContext, context)
|
|
||||||
: await authService.AuthorizeAsync(Policy, httpContext, context);
|
|
||||||
if (!authorized)
|
|
||||||
{
|
|
||||||
Fail(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static AuthorizationPolicy BuildAnyAuthorizedUserPolicy()
|
|
||||||
{
|
|
||||||
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed override void OnAuthorization([NotNull] AuthorizationContext context)
|
|
||||||
{
|
|
||||||
// The async filter will be called by the filter pipeline.
|
|
||||||
throw new NotImplementedException(Resources.AuthorizeAttribute_OnAuthorizationNotImplemented);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="IAsyncAuthorizationFilter"/>
|
||||||
|
/// </summary>
|
||||||
|
public class AuthorizeFilter : IAsyncAuthorizationFilter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Authorize filter for a specific policy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="policy"></param>
|
||||||
|
public AuthorizeFilter([NotNull] AuthorizationPolicy policy)
|
||||||
|
{
|
||||||
|
Policy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authorization policy to be used.
|
||||||
|
/// </summary>
|
||||||
|
public AuthorizationPolicy Policy { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual async Task OnAuthorizationAsync([NotNull] AuthorizationContext context)
|
||||||
|
{
|
||||||
|
// Build a ClaimsPrincipal with the Policy's required authentication types
|
||||||
|
if (Policy.ActiveAuthenticationTypes != null && Policy.ActiveAuthenticationTypes.Any())
|
||||||
|
{
|
||||||
|
var results = await context.HttpContext.AuthenticateAsync(Policy.ActiveAuthenticationTypes);
|
||||||
|
if (results != null)
|
||||||
|
{
|
||||||
|
context.HttpContext.User = new ClaimsPrincipal(results.Where(r => r.Identity != null).Select(r => r.Identity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow Anonymous skips all authorization
|
||||||
|
if (context.Filters.Any(item => item is IAllowAnonymous))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpContext = context.HttpContext;
|
||||||
|
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
|
||||||
|
|
||||||
|
// Note: Default Anonymous User is new ClaimsPrincipal(new ClaimsIdentity())
|
||||||
|
if (httpContext.User == null ||
|
||||||
|
!httpContext.User.Identities.Any(i => i.IsAuthenticated) ||
|
||||||
|
!await authService.AuthorizeAsync(httpContext.User, context, Policy))
|
||||||
|
{
|
||||||
|
context.Result = new ChallengeResult(Policy.ActiveAuthenticationTypes.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
@ -43,14 +44,14 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var action = new ActionModel(typeof(TestController).GetMethod("Edit"),
|
var action = new ActionModel(typeof(TestController).GetMethod("Edit"),
|
||||||
new List<object>() { new HttpGetAttribute() });
|
new List<object>() { new HttpGetAttribute(), new AuthorizeAttribute() });
|
||||||
|
|
||||||
action.ActionConstraints.Add(new HttpMethodConstraint(new string[] { "GET" }));
|
action.ActionConstraints.Add(new HttpMethodConstraint(new string[] { "GET" }));
|
||||||
action.ActionName = "Edit";
|
action.ActionName = "Edit";
|
||||||
|
|
||||||
action.Controller = new ControllerModel(typeof(TestController).GetTypeInfo(),
|
action.Controller = new ControllerModel(typeof(TestController).GetTypeInfo(),
|
||||||
new List<object>());
|
new List<object>());
|
||||||
action.Filters.Add(new AuthorizeAttribute());
|
action.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().Build()));
|
||||||
action.HttpMethods.Add("GET");
|
action.HttpMethods.Add("GET");
|
||||||
action.RouteConstraints.Add(new AreaAttribute("Admin"));
|
action.RouteConstraints.Add(new AreaAttribute("Admin"));
|
||||||
action.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
|
action.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
@ -49,12 +50,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var controller = new ControllerModel(typeof(TestController).GetTypeInfo(),
|
var controller = new ControllerModel(typeof(TestController).GetTypeInfo(),
|
||||||
new List<object>() { new HttpGetAttribute() });
|
new List<object>() { new HttpGetAttribute(), new AuthorizeAttribute() });
|
||||||
|
|
||||||
controller.ActionConstraints.Add(new HttpMethodConstraint(new string[] { "GET" }));
|
controller.ActionConstraints.Add(new HttpMethodConstraint(new string[] { "GET" }));
|
||||||
controller.Application = new ApplicationModel();
|
controller.Application = new ApplicationModel();
|
||||||
controller.ControllerName = "cool";
|
controller.ControllerName = "cool";
|
||||||
controller.Filters.Add(new AuthorizeAttribute());
|
controller.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().Build()));
|
||||||
controller.RouteConstraints.Add(new AreaAttribute("Admin"));
|
controller.RouteConstraints.Add(new AreaAttribute("Admin"));
|
||||||
controller.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
|
controller.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
@ -18,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_WithInheritedMethods(string methodName, bool expected)
|
public void IsAction_WithInheritedMethods(string methodName, bool expected)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(DerivedController).GetMethod(methodName);
|
var method = typeof(DerivedController).GetMethod(methodName);
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
|
|
||||||
|
|
@ -33,7 +36,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_OverridenMethodControllerClass()
|
public void IsAction_OverridenMethodControllerClass()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(BaseController).GetMethod(nameof(BaseController.Redirect));
|
var method = typeof(BaseController).GetMethod(nameof(BaseController.Redirect));
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
|
|
||||||
|
|
@ -48,7 +51,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_PrivateMethod_FromUserDefinedController()
|
public void IsAction_PrivateMethod_FromUserDefinedController()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(DerivedController).GetMethod(
|
var method = typeof(DerivedController).GetMethod(
|
||||||
"PrivateMethod",
|
"PrivateMethod",
|
||||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
|
@ -65,7 +68,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_OperatorOverloadingMethod_FromOperatorOverloadingController()
|
public void IsAction_OperatorOverloadingMethod_FromOperatorOverloadingController()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(OperatorOverloadingController).GetMethod("op_Addition");
|
var method = typeof(OperatorOverloadingController).GetMethod("op_Addition");
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
Assert.True(method.IsSpecialName);
|
Assert.True(method.IsSpecialName);
|
||||||
|
|
@ -81,7 +84,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_GenericMethod_FromUserDefinedController()
|
public void IsAction_GenericMethod_FromUserDefinedController()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(DerivedController).GetMethod("GenericMethod");
|
var method = typeof(DerivedController).GetMethod("GenericMethod");
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
|
|
||||||
|
|
@ -96,7 +99,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_OverridenNonActionMethod()
|
public void IsAction_OverridenNonActionMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(DerivedController).GetMethod("OverridenNonActionMethod");
|
var method = typeof(DerivedController).GetMethod("OverridenNonActionMethod");
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
|
|
||||||
|
|
@ -115,7 +118,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_OverriddenMethodsFromObjectClass(string methodName)
|
public void IsAction_OverriddenMethodsFromObjectClass(string methodName)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(DerivedController).GetMethod(
|
var method = typeof(DerivedController).GetMethod(
|
||||||
methodName,
|
methodName,
|
||||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
|
@ -132,7 +135,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_DerivedControllerIDisposableDisposeMethod()
|
public void IsAction_DerivedControllerIDisposableDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
||||||
var methodInfo =
|
var methodInfo =
|
||||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||||
|
|
@ -150,7 +153,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_DerivedControllerDisposeMethod()
|
public void IsAction_DerivedControllerDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
||||||
var methodInfo =
|
var methodInfo =
|
||||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||||
|
|
@ -172,7 +175,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_OverriddenDisposeMethod()
|
public void IsAction_OverriddenDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(DerivedOverriddenDisposeController).GetTypeInfo();
|
var typeInfo = typeof(DerivedOverriddenDisposeController).GetTypeInfo();
|
||||||
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
|
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
|
|
@ -188,7 +191,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_NewDisposeMethod()
|
public void IsAction_NewDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(DerivedNewDisposeController).GetTypeInfo();
|
var typeInfo = typeof(DerivedNewDisposeController).GetTypeInfo();
|
||||||
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
|
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
|
||||||
Assert.NotNull(method);
|
Assert.NotNull(method);
|
||||||
|
|
@ -204,7 +207,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_PocoControllerIDisposableDisposeMethod()
|
public void IsAction_PocoControllerIDisposableDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
|
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
|
||||||
var methodInfo =
|
var methodInfo =
|
||||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||||
|
|
@ -222,7 +225,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_PocoControllerDisposeMethod()
|
public void IsAction_PocoControllerDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
|
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
|
||||||
var methodInfo =
|
var methodInfo =
|
||||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||||
|
|
@ -244,7 +247,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_SimplePocoControllerDisposeMethod()
|
public void IsAction_SimplePocoControllerDisposeMethod()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var typeInfo = typeof(SimplePocoController).GetTypeInfo();
|
var typeInfo = typeof(SimplePocoController).GetTypeInfo();
|
||||||
var methods = typeInfo.GetMethods().Where(m => m.Name.Equals("Dispose"));
|
var methods = typeInfo.GetMethods().Where(m => m.Name.Equals("Dispose"));
|
||||||
|
|
||||||
|
|
@ -267,7 +270,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void IsAction_StaticMethods(string methodName)
|
public void IsAction_StaticMethods(string methodName)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new AccessibleActionModelBuilder();
|
var builder = CreateTestAccessibleActionModelBuilder();
|
||||||
var method = typeof(DerivedController).GetMethod(
|
var method = typeof(DerivedController).GetMethod(
|
||||||
methodName,
|
methodName,
|
||||||
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||||
|
|
@ -284,7 +287,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_ConventionallyRoutedAction_WithoutHttpConstraints()
|
public void GetActions_ConventionallyRoutedAction_WithoutHttpConstraints()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||||
var actionName = nameof(ConventionallyRoutedController.Edit);
|
var actionName = nameof(ConventionallyRoutedController.Edit);
|
||||||
|
|
||||||
|
|
@ -303,7 +306,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_ConventionallyRoutedAction_WithHttpConstraints()
|
public void GetActions_ConventionallyRoutedAction_WithHttpConstraints()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||||
var actionName = nameof(ConventionallyRoutedController.Update);
|
var actionName = nameof(ConventionallyRoutedController.Update);
|
||||||
|
|
||||||
|
|
@ -320,11 +323,34 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
Assert.IsType<CustomHttpMethodsAttribute>(Assert.Single(action.Attributes));
|
Assert.IsType<CustomHttpMethodsAttribute>(Assert.Single(action.Attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetActions_BaseAuthorizeFiltersAreStillValidWhenOverriden()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var options = new AuthorizationOptions();
|
||||||
|
options.AddPolicy("Base", policy => policy.RequiresClaim("Basic").RequiresClaim("Basic2"));
|
||||||
|
options.AddPolicy("Derived", policy => policy.RequiresClaim("Derived"));
|
||||||
|
var builder = CreateTestDefaultActionModelBuilder(options);
|
||||||
|
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
||||||
|
var actionName = nameof(DerivedController.Authorize);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var actions = builder.BuildActionModels(typeInfo, typeInfo.GetMethod(actionName));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var action = Assert.Single(actions);
|
||||||
|
Assert.Equal("Authorize", action.ActionName);
|
||||||
|
Assert.Null(action.AttributeRouteModel);
|
||||||
|
var authorizeFilters = action.Filters.OfType<AuthorizeFilter>();
|
||||||
|
Assert.Single(authorizeFilters);
|
||||||
|
Assert.Equal(3, authorizeFilters.First().Policy.Requirements.Count);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetActions_ConventionallyRoutedActionWithHttpConstraints_AndInvalidRouteTemplateProvider()
|
public void GetActions_ConventionallyRoutedActionWithHttpConstraints_AndInvalidRouteTemplateProvider()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||||
var actionName = nameof(ConventionallyRoutedController.Delete);
|
var actionName = nameof(ConventionallyRoutedController.Delete);
|
||||||
|
|
||||||
|
|
@ -346,7 +372,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_ConventionallyRoutedAction_WithMultipleHttpConstraints()
|
public void GetActions_ConventionallyRoutedAction_WithMultipleHttpConstraints()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||||
var actionName = nameof(ConventionallyRoutedController.Details);
|
var actionName = nameof(ConventionallyRoutedController.Details);
|
||||||
|
|
||||||
|
|
@ -365,7 +391,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_ConventionallyRoutedAction_WithMultipleOverlappingHttpConstraints()
|
public void GetActions_ConventionallyRoutedAction_WithMultipleOverlappingHttpConstraints()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||||
var actionName = nameof(ConventionallyRoutedController.List);
|
var actionName = nameof(ConventionallyRoutedController.List);
|
||||||
|
|
||||||
|
|
@ -385,7 +411,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_AttributeRouteOnAction()
|
public void GetActions_AttributeRouteOnAction()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||||
var actionName = nameof(NoRouteAttributeOnControllerController.Edit);
|
var actionName = nameof(NoRouteAttributeOnControllerController.Edit);
|
||||||
|
|
||||||
|
|
@ -410,7 +436,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_AttributeRouteOnAction_RouteAttribute()
|
public void GetActions_AttributeRouteOnAction_RouteAttribute()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||||
var actionName = nameof(NoRouteAttributeOnControllerController.Update);
|
var actionName = nameof(NoRouteAttributeOnControllerController.Update);
|
||||||
|
|
||||||
|
|
@ -434,7 +460,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_AttributeRouteOnAction_AcceptVerbsAttributeWithTemplate()
|
public void GetActions_AttributeRouteOnAction_AcceptVerbsAttributeWithTemplate()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||||
var actionName = nameof(NoRouteAttributeOnControllerController.List);
|
var actionName = nameof(NoRouteAttributeOnControllerController.List);
|
||||||
|
|
||||||
|
|
@ -458,7 +484,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_AttributeRouteOnAction_CreatesOneActionInforPerRouteTemplate()
|
public void GetActions_AttributeRouteOnAction_CreatesOneActionInforPerRouteTemplate()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||||
var actionName = nameof(NoRouteAttributeOnControllerController.Index);
|
var actionName = nameof(NoRouteAttributeOnControllerController.Index);
|
||||||
|
|
||||||
|
|
@ -489,7 +515,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_NoRouteOnController_AllowsConventionallyRoutedActions_OnTheSameController()
|
public void GetActions_NoRouteOnController_AllowsConventionallyRoutedActions_OnTheSameController()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||||
var actionName = nameof(NoRouteAttributeOnControllerController.Remove);
|
var actionName = nameof(NoRouteAttributeOnControllerController.Remove);
|
||||||
|
|
||||||
|
|
@ -514,7 +540,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_RouteAttributeOnController_CreatesAttributeRoute_ForNonAttributedActions(Type controller)
|
public void GetActions_RouteAttributeOnController_CreatesAttributeRoute_ForNonAttributedActions(Type controller)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = controller.GetTypeInfo();
|
var typeInfo = controller.GetTypeInfo();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -538,7 +564,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_RouteOnController_CreatesOneActionInforPerRouteTemplateOnAction(Type controller)
|
public void GetActions_RouteOnController_CreatesOneActionInforPerRouteTemplateOnAction(Type controller)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = controller.GetTypeInfo();
|
var typeInfo = controller.GetTypeInfo();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -567,7 +593,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_MixedHttpVerbsAndRoutes_EmptyVerbWithRoute()
|
public void GetActions_MixedHttpVerbsAndRoutes_EmptyVerbWithRoute()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.VerbAndRoute);
|
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.VerbAndRoute);
|
||||||
|
|
||||||
|
|
@ -584,7 +610,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyVerbsWithMultipleRoutes()
|
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyVerbsWithMultipleRoutes()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsAndRoutes);
|
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsAndRoutes);
|
||||||
|
|
||||||
|
|
@ -605,7 +631,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbsWithMultipleRoutes()
|
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbsWithMultipleRoutes()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsWithAnyWithoutTemplateAndRoutes);
|
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsWithAnyWithoutTemplateAndRoutes);
|
||||||
|
|
||||||
|
|
@ -629,7 +655,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbs()
|
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbs()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultActionModelBuilder();
|
var builder = CreateTestDefaultActionModelBuilder();
|
||||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.Invalid);
|
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.Invalid);
|
||||||
|
|
||||||
|
|
@ -646,8 +672,25 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
Assert.Equal<string>(new string[] { "GET" }, action.HttpMethods);
|
Assert.Equal<string>(new string[] { "GET" }, action.HttpMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DefaultActionModelBuilder CreateTestDefaultActionModelBuilder(
|
||||||
|
AuthorizationOptions authOptions = null)
|
||||||
|
{
|
||||||
|
var options = new Mock<IOptions<AuthorizationOptions>>();
|
||||||
|
options.Setup(o => o.Options).Returns(authOptions ?? new AuthorizationOptions());
|
||||||
|
return new DefaultActionModelBuilder(options.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AccessibleActionModelBuilder CreateTestAccessibleActionModelBuilder()
|
||||||
|
{
|
||||||
|
var options = new Mock<IOptions<AuthorizationOptions>>();
|
||||||
|
options.Setup(o => o.Options).Returns(new AuthorizationOptions());
|
||||||
|
return new AccessibleActionModelBuilder(options.Object);
|
||||||
|
}
|
||||||
|
|
||||||
private class AccessibleActionModelBuilder : DefaultActionModelBuilder
|
private class AccessibleActionModelBuilder : DefaultActionModelBuilder
|
||||||
{
|
{
|
||||||
|
public AccessibleActionModelBuilder(IOptions<AuthorizationOptions> options) : base(options) { }
|
||||||
|
|
||||||
public new bool IsAction([NotNull] TypeInfo typeInfo, [NotNull]MethodInfo methodInfo)
|
public new bool IsAction([NotNull] TypeInfo typeInfo, [NotNull]MethodInfo methodInfo)
|
||||||
{
|
{
|
||||||
return base.IsAction(typeInfo, methodInfo);
|
return base.IsAction(typeInfo, methodInfo);
|
||||||
|
|
@ -674,6 +717,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
return base.Redirect(url + "#RedirectOverride");
|
return base.Redirect(url + "#RedirectOverride");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Base")]
|
||||||
|
public virtual void Authorize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DerivedController : BaseController
|
private class DerivedController : BaseController
|
||||||
|
|
@ -691,6 +740,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Derived")]
|
||||||
|
public override void Authorize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void GenericMethod<T>()
|
public void GenericMethod<T>()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@
|
||||||
// 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.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.Filters;
|
using Microsoft.AspNet.Mvc.Filters;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
|
|
@ -15,8 +17,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void BuildControllerModel_DerivedFromControllerClass_HasFilter()
|
public void BuildControllerModel_DerivedFromControllerClass_HasFilter()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
var typeInfo = typeof(StoreController).GetTypeInfo();
|
var typeInfo = typeof(StoreController).GetTypeInfo();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -27,14 +30,31 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
Assert.IsType<ControllerActionFilter>(filter);
|
Assert.IsType<ControllerActionFilter>(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void BuildControllerModel_AuthorizeAttributeAddsAuthorizeFilter()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
var typeInfo = typeof(AccountController).GetTypeInfo();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var model = builder.BuildControllerModel(typeInfo);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(model.Filters.Any(f => f is AuthorizeFilter));
|
||||||
|
}
|
||||||
|
|
||||||
// This class has a filter attribute, but doesn't implement any filter interfaces,
|
// This class has a filter attribute, but doesn't implement any filter interfaces,
|
||||||
// so ControllerFilter is not present.
|
// so ControllerFilter is not present.
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BuildControllerModel_ClassWithoutFilterInterfaces_HasNoControllerFilter()
|
public void BuildControllerModel_ClassWithoutFilterInterfaces_HasNoControllerFilter()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
var typeInfo = typeof(NoFiltersController).GetTypeInfo();
|
var typeInfo = typeof(NoFiltersController).GetTypeInfo();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -49,8 +69,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void BuildControllerModel_ClassWithFilterInterfaces_HasFilter()
|
public void BuildControllerModel_ClassWithFilterInterfaces_HasFilter()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
var typeInfo = typeof(SomeFiltersController).GetTypeInfo();
|
var typeInfo = typeof(SomeFiltersController).GetTypeInfo();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -65,8 +86,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
public void BuildControllerModel_ClassWithFilterInterfaces_UnsupportedType()
|
public void BuildControllerModel_ClassWithFilterInterfaces_UnsupportedType()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
var typeInfo = typeof(UnsupportedFiltersController).GetTypeInfo();
|
var typeInfo = typeof(UnsupportedFiltersController).GetTypeInfo();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -81,11 +103,16 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||||
}
|
}
|
||||||
|
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
private class NoFiltersController
|
public class NoFiltersController
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SomeFiltersController : IAsyncActionFilter, IResultFilter
|
[Authorize]
|
||||||
|
public class AccountController
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SomeFiltersController : IAsyncActionFilter, IResultFilter
|
||||||
{
|
{
|
||||||
public Task OnActionExecutionAsync(
|
public Task OnActionExecutionAsync(
|
||||||
[NotNull] ActionExecutingContext context,
|
[NotNull] ActionExecutingContext context,
|
||||||
|
|
|
||||||
|
|
@ -1363,8 +1363,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
IEnumerable<IFilter> filters = null)
|
IEnumerable<IFilter> filters = null)
|
||||||
{
|
{
|
||||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { controllerTypeInfo });
|
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { controllerTypeInfo });
|
||||||
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
|
||||||
var provider = new ControllerActionDescriptorProvider(
|
var provider = new ControllerActionDescriptorProvider(
|
||||||
controllerTypeProvider,
|
controllerTypeProvider,
|
||||||
|
|
@ -1380,8 +1381,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
params TypeInfo[] controllerTypeInfo)
|
params TypeInfo[] controllerTypeInfo)
|
||||||
{
|
{
|
||||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
|
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
|
||||||
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
|
||||||
var provider = new ControllerActionDescriptorProvider(
|
var provider = new ControllerActionDescriptorProvider(
|
||||||
controllerTypeProvider,
|
controllerTypeProvider,
|
||||||
|
|
@ -1398,8 +1400,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
IApplicationModelConvention convention)
|
IApplicationModelConvention convention)
|
||||||
{
|
{
|
||||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { type });
|
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { type });
|
||||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
|
||||||
var options = new MockMvcOptionsAccessor();
|
var options = new MockMvcOptionsAccessor();
|
||||||
options.Options.Conventions.Add(convention);
|
options.Options.Conventions.Add(convention);
|
||||||
|
|
@ -1415,8 +1418,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
private IEnumerable<ActionDescriptor> GetDescriptors(params TypeInfo[] controllerTypeInfos)
|
private IEnumerable<ActionDescriptor> GetDescriptors(params TypeInfo[] controllerTypeInfos)
|
||||||
{
|
{
|
||||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfos);
|
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfos);
|
||||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
|
||||||
var provider = new ControllerActionDescriptorProvider(
|
var provider = new ControllerActionDescriptorProvider(
|
||||||
controllerTypeProvider,
|
controllerTypeProvider,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.ComponentModel.Design;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
using Microsoft.Framework.DependencyInjection.NestedProviders;
|
using Microsoft.Framework.DependencyInjection.NestedProviders;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
|
@ -123,8 +124,9 @@ namespace Microsoft.AspNet.Mvc.Logging
|
||||||
ILoggerFactory loggerFactory, params TypeInfo[] controllerTypeInfo)
|
ILoggerFactory loggerFactory, params TypeInfo[] controllerTypeInfo)
|
||||||
{
|
{
|
||||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
|
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
|
||||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
loggerFactory);
|
loggerFactory,
|
||||||
|
null);
|
||||||
|
|
||||||
var provider = new ControllerActionDescriptorProvider(
|
var provider = new ControllerActionDescriptorProvider(
|
||||||
controllerTypeProvider,
|
controllerTypeProvider,
|
||||||
|
|
|
||||||
|
|
@ -765,8 +765,9 @@ namespace Microsoft.AspNet.Mvc
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypes);
|
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypes);
|
||||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
|
||||||
return new ControllerActionDescriptorProvider(
|
return new ControllerActionDescriptorProvider(
|
||||||
controllerTypeProvider,
|
controllerTypeProvider,
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. 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.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNet.Http;
|
|
||||||
using Microsoft.AspNet.Routing;
|
|
||||||
using Microsoft.Framework.DependencyInjection;
|
|
||||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
|
||||||
using Moq;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Core.Test
|
|
||||||
{
|
|
||||||
public class AuthorizeAttributeTestsBase
|
|
||||||
{
|
|
||||||
protected AuthorizationContext GetAuthorizationContext(Action<ServiceCollection> registerServices, bool anonymous = false)
|
|
||||||
{
|
|
||||||
var validUser = new ClaimsPrincipal(
|
|
||||||
new ClaimsIdentity(
|
|
||||||
new Claim[] {
|
|
||||||
new Claim("Permission", "CanViewPage"),
|
|
||||||
new Claim(ClaimTypes.Role, "Administrator"),
|
|
||||||
new Claim(ClaimTypes.Role, "User"),
|
|
||||||
new Claim(ClaimTypes.NameIdentifier, "John")},
|
|
||||||
"Basic"));
|
|
||||||
|
|
||||||
validUser.AddIdentity(
|
|
||||||
new ClaimsIdentity(
|
|
||||||
new Claim[] {
|
|
||||||
new Claim("Permission", "CupBearer"),
|
|
||||||
new Claim(ClaimTypes.Role, "Token"),
|
|
||||||
new Claim(ClaimTypes.NameIdentifier, "John Bear")},
|
|
||||||
"Bearer"));
|
|
||||||
|
|
||||||
// ServiceProvider
|
|
||||||
var serviceCollection = new ServiceCollection();
|
|
||||||
if (registerServices != null)
|
|
||||||
{
|
|
||||||
registerServices(serviceCollection);
|
|
||||||
}
|
|
||||||
|
|
||||||
var serviceProvider = serviceCollection.BuildServiceProvider();
|
|
||||||
|
|
||||||
// HttpContext
|
|
||||||
var httpContext = new Mock<HttpContext>();
|
|
||||||
httpContext.SetupGet(c => c.User).Returns(anonymous ? null : validUser);
|
|
||||||
httpContext.SetupGet(c => c.RequestServices).Returns(serviceProvider);
|
|
||||||
|
|
||||||
// AuthorizationContext
|
|
||||||
var actionContext = new ActionContext(
|
|
||||||
httpContext: httpContext.Object,
|
|
||||||
routeData: new RouteData(),
|
|
||||||
actionDescriptor: null
|
|
||||||
);
|
|
||||||
|
|
||||||
var authorizationContext = new AuthorizationContext(
|
|
||||||
actionContext,
|
|
||||||
Enumerable.Empty<IFilter>().ToList()
|
|
||||||
);
|
|
||||||
|
|
||||||
return authorizationContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +1,39 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
// 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.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.AspNet.Security;
|
using Microsoft.AspNet.Security;
|
||||||
using Microsoft.AspNet.WebUtilities;
|
using Microsoft.AspNet.WebUtilities;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Core.Test
|
namespace Microsoft.AspNet.Mvc.Test
|
||||||
{
|
{
|
||||||
public class AuthorizeAttributeTests : AuthorizeAttributeTestsBase
|
public class AuthorizeFilterTest
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
|
public void InvalidUser()
|
||||||
|
{
|
||||||
|
var authorizationContext = GetAuthorizationContext(services => services.AddAuthorization());
|
||||||
|
Assert.True(authorizationContext.HttpContext.User.Identities.Any(i => i.IsAuthenticated));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Invoke_ValidClaimShouldNotFail()
|
public async Task Invoke_ValidClaimShouldNotFail()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewPage");
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage").Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services => services.AddAuthorization());
|
||||||
{
|
|
||||||
services.AddAuthorization(null, options =>
|
|
||||||
{
|
|
||||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage");
|
|
||||||
options.AddPolicy("CanViewPage", policy.Build());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.Null(authorizationContext.Result);
|
||||||
|
|
@ -38,13 +44,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizationOptions = new AuthorizationOptions();
|
var authorizationOptions = new AuthorizationOptions();
|
||||||
var authorizeAttribute = new AuthorizeAttribute();
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
services.AddAuthorization(),
|
services.AddAuthorization(),
|
||||||
anonymous: true);
|
anonymous: true);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
|
@ -54,7 +60,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_EmptyClaimsWithAllowAnonymousAttributeShouldNotRejectAnonymousUser()
|
public async Task Invoke_EmptyClaimsWithAllowAnonymousAttributeShouldNotRejectAnonymousUser()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute();
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization();
|
services.AddAuthorization();
|
||||||
|
|
@ -65,7 +71,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
authorizationContext.Filters.Add(new AllowAnonymousAttribute());
|
authorizationContext.Filters.Add(new AllowAnonymousAttribute());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.Null(authorizationContext.Result);
|
||||||
|
|
@ -75,7 +81,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_EmptyClaimsShouldAuthorizeAuthenticatedUser()
|
public async Task Invoke_EmptyClaimsShouldAuthorizeAuthenticatedUser()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute();
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization();
|
services.AddAuthorization();
|
||||||
|
|
@ -83,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.Null(authorizationContext.Result);
|
||||||
|
|
@ -93,19 +99,15 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_SingleValidClaimShouldSucceed()
|
public async Task Invoke_SingleValidClaimShouldSucceed()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewCommentOrPage");
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment", "CanViewPage").Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization(null, options =>
|
services.AddAuthorization();
|
||||||
{
|
|
||||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment", "CanViewPage");
|
|
||||||
options.AddPolicy("CanViewCommentOrPage", policy.Build());
|
|
||||||
});
|
|
||||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.Null(authorizationContext.Result);
|
||||||
|
|
@ -115,7 +117,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_RequireAdminRoleShouldFailWithNoHandlers()
|
public async Task Invoke_RequireAdminRoleShouldFailWithNoHandlers()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator" };
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresRole("Administrator").Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
|
|
@ -123,7 +125,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
|
@ -133,7 +135,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_RequireAdminAndUserRoleWithNoPolicyShouldSucceed()
|
public async Task Invoke_RequireAdminAndUserRoleWithNoPolicyShouldSucceed()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator,User" };
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresRole("Administrator").Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization();
|
services.AddAuthorization();
|
||||||
|
|
@ -141,7 +143,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.Null(authorizationContext.Result);
|
||||||
|
|
@ -151,7 +153,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_RequireUnknownRoleShouldFail()
|
public async Task Invoke_RequireUnknownRoleShouldFail()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Wut" };
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresRole("Wut").Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization();
|
services.AddAuthorization();
|
||||||
|
|
@ -159,7 +161,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
|
@ -169,19 +171,18 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_RequireAdminRoleButFailPolicyShouldFail()
|
public async Task Invoke_RequireAdminRoleButFailPolicyShouldFail()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator", Policy = "Basic" };
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||||
|
.RequiresRole("Administrator")
|
||||||
|
.RequiresClaim("Permission", "CanViewComment")
|
||||||
|
.Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization(null, options =>
|
services.AddAuthorization();
|
||||||
{
|
|
||||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment");
|
|
||||||
options.AddPolicy("CanViewComment", policy.Build());
|
|
||||||
});
|
|
||||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
|
@ -191,19 +192,17 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_InvalidClaimShouldFail()
|
public async Task Invoke_InvalidClaimShouldFail()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewComment");
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||||
|
.RequiresClaim("Permission", "CanViewComment")
|
||||||
|
.Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization(null, options =>
|
services.AddAuthorization();
|
||||||
{
|
|
||||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment");
|
|
||||||
options.AddPolicy("CanViewComment", policy.Build());
|
|
||||||
});
|
|
||||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
|
@ -216,14 +215,16 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
bool authorizationServiceIsCalled = false;
|
bool authorizationServiceIsCalled = false;
|
||||||
var authorizationService = new Mock<IAuthorizationService>();
|
var authorizationService = new Mock<IAuthorizationService>();
|
||||||
authorizationService
|
authorizationService
|
||||||
.Setup(x => x.AuthorizeAsync("CanViewComment", null, null))
|
.Setup(x => x.AuthorizeAsync(null, null, "CanViewComment"))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
authorizationServiceIsCalled = true;
|
authorizationServiceIsCalled = true;
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewComment");
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||||
|
.RequiresClaim("Permission", "CanViewComment")
|
||||||
|
.Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
services.AddInstance(authorizationService.Object)
|
services.AddInstance(authorizationService.Object)
|
||||||
);
|
);
|
||||||
|
|
@ -231,7 +232,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
authorizationContext.Result = new HttpStatusCodeResult(StatusCodes.Status401Unauthorized);
|
authorizationContext.Result = new HttpStatusCodeResult(StatusCodes.Status401Unauthorized);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(authorizationServiceIsCalled);
|
Assert.False(authorizationServiceIsCalled);
|
||||||
|
|
@ -241,19 +242,17 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_FailWhenLookingForClaimInOtherIdentity()
|
public async Task Invoke_FailWhenLookingForClaimInOtherIdentity()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewComment");
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||||
|
.RequiresClaim("Permission", "CanViewComment")
|
||||||
|
.Build());
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization(null, options =>
|
services.AddAuthorization();
|
||||||
{
|
|
||||||
var policy = new AuthorizationPolicyBuilder("Bearer").RequiresClaim("Permission", "CanViewComment");
|
|
||||||
options.AddPolicy("CanViewComment", policy.Build());
|
|
||||||
});
|
|
||||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
|
@ -263,30 +262,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public async Task Invoke_CanLookingForClaimsInMultipleIdentities()
|
public async Task Invoke_CanLookingForClaimsInMultipleIdentities()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewCommentCupBearer");
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder("Basic", "Bearer")
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
.RequiresClaim("Permission", "CanViewComment")
|
||||||
{
|
.RequiresClaim("Permission", "CupBearer")
|
||||||
services.AddAuthorization(null, options =>
|
.Build());
|
||||||
{
|
|
||||||
var policy = new AuthorizationPolicyBuilder("Basic", "Bearer")
|
|
||||||
.RequiresClaim("Permission", "CanViewComment")
|
|
||||||
.RequiresClaim("Permission", "CupBearer");
|
|
||||||
options.AddPolicy("CanViewComment", policy.Build());
|
|
||||||
});
|
|
||||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.NotNull(authorizationContext.Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Invoke_NoPoliciesShouldNotFail()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var authorizeAttribute = new AuthorizeAttribute("CanViewPage");
|
|
||||||
var authorizationContext = GetAuthorizationContext(services =>
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
{
|
{
|
||||||
services.AddAuthorization();
|
services.AddAuthorization();
|
||||||
|
|
@ -294,10 +273,80 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(authorizationContext.Result);
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Invoke_EmptyPolicyWillFail()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().Build());
|
||||||
|
var authorizationContext = GetAuthorizationContext(services =>
|
||||||
|
{
|
||||||
|
services.AddAuthorization();
|
||||||
|
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(authorizationContext.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthorizationContext GetAuthorizationContext(Action<ServiceCollection> registerServices, bool anonymous = false)
|
||||||
|
{
|
||||||
|
var validUser = new ClaimsPrincipal(
|
||||||
|
new ClaimsIdentity(
|
||||||
|
new Claim[] {
|
||||||
|
new Claim("Permission", "CanViewPage"),
|
||||||
|
new Claim(ClaimTypes.Role, "Administrator"),
|
||||||
|
new Claim(ClaimTypes.Role, "User"),
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, "John")},
|
||||||
|
"Basic"));
|
||||||
|
|
||||||
|
validUser.AddIdentity(
|
||||||
|
new ClaimsIdentity(
|
||||||
|
new Claim[] {
|
||||||
|
new Claim("Permission", "CupBearer"),
|
||||||
|
new Claim(ClaimTypes.Role, "Token"),
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, "John Bear")},
|
||||||
|
"Bearer"));
|
||||||
|
|
||||||
|
// ServiceProvider
|
||||||
|
var serviceCollection = new ServiceCollection();
|
||||||
|
if (registerServices != null)
|
||||||
|
{
|
||||||
|
registerServices(serviceCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||||
|
|
||||||
|
// HttpContext
|
||||||
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
httpContext.SetupProperty(c => c.User);
|
||||||
|
if (!anonymous)
|
||||||
|
{
|
||||||
|
httpContext.Object.User = validUser;
|
||||||
|
}
|
||||||
|
httpContext.SetupGet(c => c.RequestServices).Returns(serviceProvider);
|
||||||
|
|
||||||
|
// AuthorizationContext
|
||||||
|
var actionContext = new ActionContext(
|
||||||
|
httpContext: httpContext.Object,
|
||||||
|
routeData: new RouteData(),
|
||||||
|
actionDescriptor: null
|
||||||
|
);
|
||||||
|
|
||||||
|
var authorizationContext = new AuthorizationContext(
|
||||||
|
actionContext,
|
||||||
|
Enumerable.Empty<IFilter>().ToList()
|
||||||
|
);
|
||||||
|
|
||||||
|
return authorizationContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,8 +106,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
Assert.Equal("4", await response.Content.ReadAsStringAsync());
|
Assert.Equal("4", await response.Content.ReadAsStringAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CanAuthorizeParticularUsers()
|
[Theory]
|
||||||
|
[InlineData("AdminRole")]
|
||||||
|
[InlineData("InteractiveUsers")]
|
||||||
|
[InlineData("ApiManagers")]
|
||||||
|
public async Task CanAuthorize(string testAction)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestServer.Create(_services, _app);
|
var server = TestServer.Create(_services, _app);
|
||||||
|
|
@ -115,7 +119,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.GetAsync(
|
var response = await client.GetAsync(
|
||||||
"http://localhost/AuthorizeUser/ReturnHelloWorldOnlyForAuthorizedUser");
|
"http://localhost/AuthorizeUser/"+testAction);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
|
||||||
|
|
@ -372,8 +372,9 @@ namespace System.Web.Http
|
||||||
var assemblyProvider = new FixedSetAssemblyProvider();
|
var assemblyProvider = new FixedSetAssemblyProvider();
|
||||||
assemblyProvider.CandidateAssemblies.Add(GetType().GetTypeInfo().Assembly);
|
assemblyProvider.CandidateAssemblies.Add(GetType().GetTypeInfo().Assembly);
|
||||||
var controllerTypeProvider = new NamespaceFilteredControllerTypeProvider(assemblyProvider);
|
var controllerTypeProvider = new NamespaceFilteredControllerTypeProvider(assemblyProvider);
|
||||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance,
|
||||||
|
null);
|
||||||
|
|
||||||
var filterProvider = new Mock<IGlobalFilterProvider>();
|
var filterProvider = new Mock<IGlobalFilterProvider>();
|
||||||
filterProvider
|
filterProvider
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http.Security;
|
using Microsoft.AspNet.Http.Security;
|
||||||
using Microsoft.AspNet.Security;
|
using Microsoft.AspNet.Security;
|
||||||
|
|
@ -11,51 +12,21 @@ using Microsoft.Framework.OptionsModel;
|
||||||
|
|
||||||
namespace FiltersWebSite
|
namespace FiltersWebSite
|
||||||
{
|
{
|
||||||
public class BasicOptions : AuthenticationOptions
|
|
||||||
{
|
|
||||||
public BasicOptions()
|
|
||||||
{
|
|
||||||
AuthenticationType = "Basic";
|
|
||||||
AuthenticationMode = AuthenticationMode.Passive;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AuthorizeBasicMiddleware : AuthenticationMiddleware<BasicOptions>
|
public class AuthorizeBasicMiddleware : AuthenticationMiddleware<BasicOptions>
|
||||||
{
|
{
|
||||||
public AuthorizeBasicMiddleware(
|
public AuthorizeBasicMiddleware(
|
||||||
RequestDelegate next,
|
RequestDelegate next,
|
||||||
IServiceProvider services,
|
IServiceProvider services,
|
||||||
IOptions<BasicOptions> options) :
|
IOptions<BasicOptions> options,
|
||||||
base(next, services, options, null)
|
string authType) :
|
||||||
{ }
|
base(next, services, options,
|
||||||
|
new ConfigureOptions<BasicOptions>(o => o.AuthenticationType = authType) { Name = authType })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override AuthenticationHandler<BasicOptions> CreateHandler()
|
protected override AuthenticationHandler<BasicOptions> CreateHandler()
|
||||||
{
|
{
|
||||||
return new BasicAuthenticationHandler();
|
return new BasicAuthenticationHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BasicAuthenticationHandler : AuthenticationHandler<BasicOptions>
|
|
||||||
{
|
|
||||||
protected override void ApplyResponseChallenge()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ApplyResponseGrant()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override AuthenticationTicket AuthenticateCore()
|
|
||||||
{
|
|
||||||
var id = new ClaimsIdentity(
|
|
||||||
new Claim[] {
|
|
||||||
new Claim("Permission", "CanViewPage"),
|
|
||||||
new Claim(ClaimTypes.Role, "Administrator"),
|
|
||||||
new Claim(ClaimTypes.NameIdentifier, "John")},
|
|
||||||
"Basic");
|
|
||||||
|
|
||||||
return new AuthenticationTicket(id, new AuthenticationProperties());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Http.Security;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
using Microsoft.AspNet.Security.Infrastructure;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
|
|
||||||
|
namespace FiltersWebSite
|
||||||
|
{
|
||||||
|
public class BasicAuthenticationHandler : AuthenticationHandler<BasicOptions>
|
||||||
|
{
|
||||||
|
protected override void ApplyResponseChallenge()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyResponseGrant()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override AuthenticationTicket AuthenticateCore()
|
||||||
|
{
|
||||||
|
var id = new ClaimsIdentity(
|
||||||
|
new Claim[] {
|
||||||
|
new Claim("Permission", "CanViewPage"),
|
||||||
|
new Claim("Manager", "yes"),
|
||||||
|
new Claim(ClaimTypes.Role, "Administrator"),
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, "John")
|
||||||
|
},
|
||||||
|
Options.AuthenticationType);
|
||||||
|
return new AuthenticationTicket(id, new AuthenticationProperties());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Http.Security;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
using Microsoft.AspNet.Security.Infrastructure;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
|
|
||||||
|
namespace FiltersWebSite
|
||||||
|
{
|
||||||
|
public class BasicOptions : AuthenticationOptions
|
||||||
|
{
|
||||||
|
public BasicOptions()
|
||||||
|
{
|
||||||
|
AuthenticationMode = AuthenticationMode.Passive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,15 +2,27 @@
|
||||||
// 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 Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
|
||||||
namespace FiltersWebSite
|
namespace FiltersWebSite
|
||||||
{
|
{
|
||||||
[AuthorizeUser]
|
[Authorize("Api")]
|
||||||
[Authorize("RequireBasic")]
|
|
||||||
public class AuthorizeUserController : Controller
|
public class AuthorizeUserController : Controller
|
||||||
{
|
{
|
||||||
[Authorize("CanViewPage")]
|
[Authorize("Api-Manager")]
|
||||||
public string ReturnHelloWorldOnlyForAuthorizedUser()
|
public string ApiManagers()
|
||||||
|
{
|
||||||
|
return "Hello World!";
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "Administrator")]
|
||||||
|
public string AdminRole()
|
||||||
|
{
|
||||||
|
return "Hello World!";
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize("Interactive")]
|
||||||
|
public string InteractiveUsers()
|
||||||
{
|
{
|
||||||
return "Hello World!";
|
return "Hello World!";
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +39,5 @@ namespace FiltersWebSite
|
||||||
{
|
{
|
||||||
return "Hello World!";
|
return "Hello World!";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
|
||||||
|
namespace FiltersWebSite
|
||||||
|
{
|
||||||
|
public class ManagerHandler : AuthorizationHandler<OperationAuthorizationRequirement>
|
||||||
|
{
|
||||||
|
public override void Handle(Microsoft.AspNet.Security.AuthorizationContext context, OperationAuthorizationRequirement requirement)
|
||||||
|
{
|
||||||
|
if (context.User.HasClaim("Manager", "yes"))
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNet.Security;
|
||||||
|
|
||||||
|
namespace FiltersWebSite
|
||||||
|
{
|
||||||
|
public static class Operations
|
||||||
|
{
|
||||||
|
public static OperationAuthorizationRequirement Edit = new OperationAuthorizationRequirement { Name = "Edit" };
|
||||||
|
public static OperationAuthorizationRequirement Create = new OperationAuthorizationRequirement { Name = "Create" };
|
||||||
|
public static OperationAuthorizationRequirement Delete = new OperationAuthorizationRequirement { Name = "Delete" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// 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.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Security;
|
using Microsoft.AspNet.Security;
|
||||||
|
|
@ -18,23 +19,32 @@ namespace FiltersWebSite
|
||||||
app.UseServices(services =>
|
app.UseServices(services =>
|
||||||
{
|
{
|
||||||
services.AddMvc(configuration);
|
services.AddMvc(configuration);
|
||||||
services.Configure<AuthorizationOptions>(options =>
|
services.ConfigureAuthorization(options =>
|
||||||
{
|
{
|
||||||
// This policy cannot succeed since it has no requirements
|
// This policy cannot succeed since it has no requirements
|
||||||
options.AddPolicy("Impossible",
|
options.AddPolicy("Impossible", policy => { });
|
||||||
new AuthorizationPolicyBuilder()
|
options.AddPolicy("Api", policy =>
|
||||||
.Build());
|
{
|
||||||
options.AddPolicy("RequireBasic",
|
policy.ActiveAuthenticationTypes.Add("Api");
|
||||||
new AuthorizationPolicyBuilder("Basic")
|
policy.RequiresClaim(ClaimTypes.NameIdentifier);
|
||||||
.RequiresClaim(ClaimTypes.NameIdentifier)
|
});
|
||||||
.Build());
|
options.AddPolicy("Api-Manager", policy =>
|
||||||
options.AddPolicy("CanViewPage",
|
{
|
||||||
new AuthorizationPolicyBuilder()
|
policy.ActiveAuthenticationTypes.Add("Api");
|
||||||
.RequiresClaim("Permission", "CanViewPage")
|
policy.Requirements.Add(Operations.Edit);
|
||||||
.Build());
|
});
|
||||||
|
options.AddPolicy("Interactive", policy =>
|
||||||
|
{
|
||||||
|
policy.ActiveAuthenticationTypes.Add("Interactive");
|
||||||
|
policy.RequiresClaim(ClaimTypes.NameIdentifier)
|
||||||
|
.RequiresClaim("Permission", "CanViewPage");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
services.AddSingleton<RandomNumberFilter>();
|
services.AddSingleton<RandomNumberFilter>();
|
||||||
services.AddSingleton<RandomNumberService>();
|
services.AddSingleton<RandomNumberService>();
|
||||||
|
services.AddTransient<IAuthorizationHandler, ManagerHandler>();
|
||||||
|
services.Configure<BasicOptions>(o => o.AuthenticationType = "Api", "Api");
|
||||||
|
services.Configure<BasicOptions>(o => o.AuthenticationType = "Interactive", "Interactive");
|
||||||
|
|
||||||
services.Configure<MvcOptions>(options =>
|
services.Configure<MvcOptions>(options =>
|
||||||
{
|
{
|
||||||
|
|
@ -48,7 +58,8 @@ namespace FiltersWebSite
|
||||||
|
|
||||||
app.UseErrorReporter();
|
app.UseErrorReporter();
|
||||||
|
|
||||||
app.UseMiddleware<AuthorizeBasicMiddleware>();
|
app.UseMiddleware<AuthorizeBasicMiddleware>("Interactive");
|
||||||
|
app.UseMiddleware<AuthorizeBasicMiddleware>("Api");
|
||||||
|
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue