React to Authorize changes
This commit is contained in:
parent
3d30fd653e
commit
94ef6cf8fa
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Security;
|
||||
using MvcSample.Web.Filters;
|
||||
using MvcSample.Web.Models;
|
||||
|
||||
|
|
@ -50,14 +51,12 @@ namespace MvcSample.Web
|
|||
return new ChallengeResult();
|
||||
}
|
||||
|
||||
[Authorize("CanViewPage")]
|
||||
public ActionResult NotGrantedClaim(int age = 20, string userName = "SampleUser")
|
||||
{
|
||||
return Index(age, userName);
|
||||
}
|
||||
|
||||
[FakeUser]
|
||||
[Authorize("CanViewAnything")]
|
||||
public ActionResult AllGranted(int age = 20, string userName = "SampleUser")
|
||||
{
|
||||
return Index(age, userName);
|
||||
|
|
|
|||
|
|
@ -40,19 +40,6 @@ namespace MvcSample.Web
|
|||
|
||||
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.AddSingleton<PassThroughAttribute>();
|
||||
services.AddSingleton<UserNameService>();
|
||||
|
|
@ -131,4 +118,4 @@ namespace MvcSample.Web
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ using System.Reflection;
|
|||
using Microsoft.AspNet.Mvc.Description;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Routing;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||
{
|
||||
|
|
@ -16,6 +18,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
/// </summary>
|
||||
public class DefaultActionModelBuilder : IActionModelBuilder
|
||||
{
|
||||
private readonly AuthorizationOptions _authorizationOptions;
|
||||
|
||||
public DefaultActionModelBuilder(IOptions<AuthorizationOptions> options)
|
||||
{
|
||||
_authorizationOptions = options?.Options ?? new AuthorizationOptions();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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.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();
|
||||
if (actionName?.Name != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ using System.Reflection;
|
|||
using Microsoft.AspNet.Mvc.Description;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Mvc.Routing;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||
{
|
||||
|
|
@ -19,15 +21,20 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
{
|
||||
private readonly IActionModelBuilder _actionModelBuilder;
|
||||
private readonly ILogger _logger;
|
||||
private readonly AuthorizationOptions _authorizationOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="DefaultControllerModelBuilder"/>.
|
||||
/// </summary>
|
||||
/// <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;
|
||||
_logger = loggerFactory.Create<DefaultControllerModelBuilder>();
|
||||
_authorizationOptions = options?.Options ?? new AuthorizationOptions();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -72,6 +79,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
AddRange(controllerModel.Filters, attributes.OfType<IFilter>());
|
||||
AddRange(controllerModel.RouteConstraints, attributes.OfType<IRouteConstraintProvider>());
|
||||
|
||||
var policy = AuthorizationPolicy.Combine(_authorizationOptions, attributes.OfType<AuthorizeAttribute>());
|
||||
if (policy != null)
|
||||
{
|
||||
controllerModel.Filters.Add(new AuthorizeFilter(policy));
|
||||
}
|
||||
|
||||
AddRange(
|
||||
controllerModel.AttributeRoutes,
|
||||
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.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||
|
|
@ -43,14 +44,14 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
{
|
||||
// Arrange
|
||||
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.ActionName = "Edit";
|
||||
|
||||
action.Controller = new ControllerModel(typeof(TestController).GetTypeInfo(),
|
||||
new List<object>());
|
||||
action.Filters.Add(new AuthorizeAttribute());
|
||||
action.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().Build()));
|
||||
action.HttpMethods.Add("GET");
|
||||
action.RouteConstraints.Add(new AreaAttribute("Admin"));
|
||||
action.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||
|
|
@ -49,12 +50,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
{
|
||||
// Arrange
|
||||
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.Application = new ApplicationModel();
|
||||
controller.ControllerName = "cool";
|
||||
controller.Filters.Add(new AuthorizeAttribute());
|
||||
controller.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().Build()));
|
||||
controller.RouteConstraints.Add(new AreaAttribute("Admin"));
|
||||
controller.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||
|
|
@ -18,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_WithInheritedMethods(string methodName, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(DerivedController).GetMethod(methodName);
|
||||
Assert.NotNull(method);
|
||||
|
||||
|
|
@ -33,7 +36,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_OverridenMethodControllerClass()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(BaseController).GetMethod(nameof(BaseController.Redirect));
|
||||
Assert.NotNull(method);
|
||||
|
||||
|
|
@ -48,7 +51,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_PrivateMethod_FromUserDefinedController()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(DerivedController).GetMethod(
|
||||
"PrivateMethod",
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
|
@ -65,7 +68,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_OperatorOverloadingMethod_FromOperatorOverloadingController()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(OperatorOverloadingController).GetMethod("op_Addition");
|
||||
Assert.NotNull(method);
|
||||
Assert.True(method.IsSpecialName);
|
||||
|
|
@ -81,7 +84,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_GenericMethod_FromUserDefinedController()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(DerivedController).GetMethod("GenericMethod");
|
||||
Assert.NotNull(method);
|
||||
|
||||
|
|
@ -96,7 +99,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_OverridenNonActionMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(DerivedController).GetMethod("OverridenNonActionMethod");
|
||||
Assert.NotNull(method);
|
||||
|
||||
|
|
@ -115,7 +118,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_OverriddenMethodsFromObjectClass(string methodName)
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(DerivedController).GetMethod(
|
||||
methodName,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
|
@ -132,7 +135,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_DerivedControllerIDisposableDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
||||
var methodInfo =
|
||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||
|
|
@ -150,7 +153,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_DerivedControllerDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(DerivedController).GetTypeInfo();
|
||||
var methodInfo =
|
||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||
|
|
@ -172,7 +175,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_OverriddenDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(DerivedOverriddenDisposeController).GetTypeInfo();
|
||||
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
|
||||
Assert.NotNull(method);
|
||||
|
|
@ -188,7 +191,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_NewDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(DerivedNewDisposeController).GetTypeInfo();
|
||||
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
|
||||
Assert.NotNull(method);
|
||||
|
|
@ -204,7 +207,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_PocoControllerIDisposableDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
|
||||
var methodInfo =
|
||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||
|
|
@ -222,7 +225,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_PocoControllerDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
|
||||
var methodInfo =
|
||||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
|
||||
|
|
@ -244,7 +247,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void IsAction_SimplePocoControllerDisposeMethod()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var typeInfo = typeof(SimplePocoController).GetTypeInfo();
|
||||
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)
|
||||
{
|
||||
// Arrange
|
||||
var builder = new AccessibleActionModelBuilder();
|
||||
var builder = CreateTestAccessibleActionModelBuilder();
|
||||
var method = typeof(DerivedController).GetMethod(
|
||||
methodName,
|
||||
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
|
|
@ -284,7 +287,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_ConventionallyRoutedAction_WithoutHttpConstraints()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||
var actionName = nameof(ConventionallyRoutedController.Edit);
|
||||
|
||||
|
|
@ -303,7 +306,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_ConventionallyRoutedAction_WithHttpConstraints()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||
var actionName = nameof(ConventionallyRoutedController.Update);
|
||||
|
||||
|
|
@ -320,11 +323,34 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
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]
|
||||
public void GetActions_ConventionallyRoutedActionWithHttpConstraints_AndInvalidRouteTemplateProvider()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||
var actionName = nameof(ConventionallyRoutedController.Delete);
|
||||
|
||||
|
|
@ -346,7 +372,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_ConventionallyRoutedAction_WithMultipleHttpConstraints()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||
var actionName = nameof(ConventionallyRoutedController.Details);
|
||||
|
||||
|
|
@ -365,7 +391,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_ConventionallyRoutedAction_WithMultipleOverlappingHttpConstraints()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
|
||||
var actionName = nameof(ConventionallyRoutedController.List);
|
||||
|
||||
|
|
@ -385,7 +411,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_AttributeRouteOnAction()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||
var actionName = nameof(NoRouteAttributeOnControllerController.Edit);
|
||||
|
||||
|
|
@ -410,7 +436,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_AttributeRouteOnAction_RouteAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||
var actionName = nameof(NoRouteAttributeOnControllerController.Update);
|
||||
|
||||
|
|
@ -434,7 +460,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_AttributeRouteOnAction_AcceptVerbsAttributeWithTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||
var actionName = nameof(NoRouteAttributeOnControllerController.List);
|
||||
|
||||
|
|
@ -458,7 +484,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_AttributeRouteOnAction_CreatesOneActionInforPerRouteTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||
var actionName = nameof(NoRouteAttributeOnControllerController.Index);
|
||||
|
||||
|
|
@ -489,7 +515,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_NoRouteOnController_AllowsConventionallyRoutedActions_OnTheSameController()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
|
||||
var actionName = nameof(NoRouteAttributeOnControllerController.Remove);
|
||||
|
||||
|
|
@ -514,7 +540,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_RouteAttributeOnController_CreatesAttributeRoute_ForNonAttributedActions(Type controller)
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = controller.GetTypeInfo();
|
||||
|
||||
// Act
|
||||
|
|
@ -538,7 +564,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_RouteOnController_CreatesOneActionInforPerRouteTemplateOnAction(Type controller)
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = controller.GetTypeInfo();
|
||||
|
||||
// Act
|
||||
|
|
@ -567,7 +593,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_MixedHttpVerbsAndRoutes_EmptyVerbWithRoute()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.VerbAndRoute);
|
||||
|
||||
|
|
@ -584,7 +610,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyVerbsWithMultipleRoutes()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsAndRoutes);
|
||||
|
||||
|
|
@ -605,7 +631,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbsWithMultipleRoutes()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsWithAnyWithoutTemplateAndRoutes);
|
||||
|
||||
|
|
@ -629,7 +655,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbs()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultActionModelBuilder();
|
||||
var builder = CreateTestDefaultActionModelBuilder();
|
||||
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
|
||||
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.Invalid);
|
||||
|
||||
|
|
@ -646,8 +672,25 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
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
|
||||
{
|
||||
public AccessibleActionModelBuilder(IOptions<AuthorizationOptions> options) : base(options) { }
|
||||
|
||||
public new bool IsAction([NotNull] TypeInfo typeInfo, [NotNull]MethodInfo methodInfo)
|
||||
{
|
||||
return base.IsAction(typeInfo, methodInfo);
|
||||
|
|
@ -674,6 +717,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
{
|
||||
return base.Redirect(url + "#RedirectOverride");
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Base")]
|
||||
public virtual void Authorize()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class DerivedController : BaseController
|
||||
|
|
@ -691,6 +740,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
{
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Derived")]
|
||||
public override void Authorize()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ApplicationModels
|
||||
|
|
@ -15,8 +17,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void BuildControllerModel_DerivedFromControllerClass_HasFilter()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
var typeInfo = typeof(StoreController).GetTypeInfo();
|
||||
|
||||
// Act
|
||||
|
|
@ -27,14 +30,31 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
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,
|
||||
// so ControllerFilter is not present.
|
||||
[Fact]
|
||||
public void BuildControllerModel_ClassWithoutFilterInterfaces_HasNoControllerFilter()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
var typeInfo = typeof(NoFiltersController).GetTypeInfo();
|
||||
|
||||
// Act
|
||||
|
|
@ -49,8 +69,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void BuildControllerModel_ClassWithFilterInterfaces_HasFilter()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
var typeInfo = typeof(SomeFiltersController).GetTypeInfo();
|
||||
|
||||
// Act
|
||||
|
|
@ -65,8 +86,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
public void BuildControllerModel_ClassWithFilterInterfaces_UnsupportedType()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
var typeInfo = typeof(UnsupportedFiltersController).GetTypeInfo();
|
||||
|
||||
// Act
|
||||
|
|
@ -81,11 +103,16 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
}
|
||||
|
||||
[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(
|
||||
[NotNull] ActionExecutingContext context,
|
||||
|
|
@ -121,4 +148,4 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1363,8 +1363,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<IFilter> filters = null)
|
||||
{
|
||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { controllerTypeInfo });
|
||||
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
|
||||
var provider = new ControllerActionDescriptorProvider(
|
||||
controllerTypeProvider,
|
||||
|
|
@ -1380,8 +1381,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
params TypeInfo[] controllerTypeInfo)
|
||||
{
|
||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
|
||||
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
|
||||
var provider = new ControllerActionDescriptorProvider(
|
||||
controllerTypeProvider,
|
||||
|
|
@ -1398,8 +1400,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IApplicationModelConvention convention)
|
||||
{
|
||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { type });
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
|
||||
var options = new MockMvcOptionsAccessor();
|
||||
options.Options.Conventions.Add(convention);
|
||||
|
|
@ -1415,8 +1418,9 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
private IEnumerable<ActionDescriptor> GetDescriptors(params TypeInfo[] controllerTypeInfos)
|
||||
{
|
||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfos);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
|
||||
var provider = new ControllerActionDescriptorProvider(
|
||||
controllerTypeProvider,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.ComponentModel.Design;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.NestedProviders;
|
||||
using Microsoft.Framework.Logging;
|
||||
|
|
@ -123,8 +124,9 @@ namespace Microsoft.AspNet.Mvc.Logging
|
|||
ILoggerFactory loggerFactory, params TypeInfo[] controllerTypeInfo)
|
||||
{
|
||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
loggerFactory);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
loggerFactory,
|
||||
null);
|
||||
|
||||
var provider = new ControllerActionDescriptorProvider(
|
||||
controllerTypeProvider,
|
||||
|
|
|
|||
|
|
@ -765,8 +765,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
.ToList();
|
||||
|
||||
var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypes);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
|
||||
return new ControllerActionDescriptorProvider(
|
||||
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.
|
||||
// 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 Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Security;
|
||||
using Microsoft.AspNet.WebUtilities;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Moq;
|
||||
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]
|
||||
public async Task Invoke_ValidClaimShouldNotFail()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute("CanViewPage");
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization(null, options =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage");
|
||||
options.AddPolicy("CanViewPage", policy.Build());
|
||||
});
|
||||
});
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage").Build());
|
||||
var authorizationContext = GetAuthorizationContext(services => services.AddAuthorization());
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.Null(authorizationContext.Result);
|
||||
|
|
@ -38,13 +44,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
{
|
||||
// Arrange
|
||||
var authorizationOptions = new AuthorizationOptions();
|
||||
var authorizeAttribute = new AuthorizeAttribute();
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
services.AddAuthorization(),
|
||||
anonymous: true);
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(authorizationContext.Result);
|
||||
|
|
@ -54,7 +60,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_EmptyClaimsWithAllowAnonymousAttributeShouldNotRejectAnonymousUser()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute();
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization();
|
||||
|
|
@ -65,7 +71,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
authorizationContext.Filters.Add(new AllowAnonymousAttribute());
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.Null(authorizationContext.Result);
|
||||
|
|
@ -75,7 +81,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_EmptyClaimsShouldAuthorizeAuthenticatedUser()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute();
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization();
|
||||
|
|
@ -83,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.Null(authorizationContext.Result);
|
||||
|
|
@ -93,19 +99,15 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_SingleValidClaimShouldSucceed()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute("CanViewCommentOrPage");
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment", "CanViewPage").Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization(null, options =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment", "CanViewPage");
|
||||
options.AddPolicy("CanViewCommentOrPage", policy.Build());
|
||||
});
|
||||
services.AddAuthorization();
|
||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.Null(authorizationContext.Result);
|
||||
|
|
@ -115,7 +117,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_RequireAdminRoleShouldFailWithNoHandlers()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator" };
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresRole("Administrator").Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddOptions();
|
||||
|
|
@ -123,7 +125,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(authorizationContext.Result);
|
||||
|
|
@ -133,7 +135,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_RequireAdminAndUserRoleWithNoPolicyShouldSucceed()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Administrator,User" };
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresRole("Administrator").Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization();
|
||||
|
|
@ -141,7 +143,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.Null(authorizationContext.Result);
|
||||
|
|
@ -151,7 +153,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_RequireUnknownRoleShouldFail()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute { Roles = "Wut" };
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequiresRole("Wut").Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization();
|
||||
|
|
@ -159,7 +161,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(authorizationContext.Result);
|
||||
|
|
@ -169,19 +171,18 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_RequireAdminRoleButFailPolicyShouldFail()
|
||||
{
|
||||
// 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 =>
|
||||
{
|
||||
services.AddAuthorization(null, options =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment");
|
||||
options.AddPolicy("CanViewComment", policy.Build());
|
||||
});
|
||||
services.AddAuthorization();
|
||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(authorizationContext.Result);
|
||||
|
|
@ -191,19 +192,17 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_InvalidClaimShouldFail()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute("CanViewComment");
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||
.RequiresClaim("Permission", "CanViewComment")
|
||||
.Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization(null, options =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewComment");
|
||||
options.AddPolicy("CanViewComment", policy.Build());
|
||||
});
|
||||
services.AddAuthorization();
|
||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(authorizationContext.Result);
|
||||
|
|
@ -216,14 +215,16 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
bool authorizationServiceIsCalled = false;
|
||||
var authorizationService = new Mock<IAuthorizationService>();
|
||||
authorizationService
|
||||
.Setup(x => x.AuthorizeAsync("CanViewComment", null, null))
|
||||
.Setup(x => x.AuthorizeAsync(null, null, "CanViewComment"))
|
||||
.Returns(() =>
|
||||
{
|
||||
authorizationServiceIsCalled = true;
|
||||
return Task.FromResult(true);
|
||||
});
|
||||
|
||||
var authorizeAttribute = new AuthorizeAttribute("CanViewComment");
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||
.RequiresClaim("Permission", "CanViewComment")
|
||||
.Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
services.AddInstance(authorizationService.Object)
|
||||
);
|
||||
|
|
@ -231,7 +232,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
authorizationContext.Result = new HttpStatusCodeResult(StatusCodes.Status401Unauthorized);
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.False(authorizationServiceIsCalled);
|
||||
|
|
@ -241,19 +242,17 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_FailWhenLookingForClaimInOtherIdentity()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute("CanViewComment");
|
||||
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder()
|
||||
.RequiresClaim("Permission", "CanViewComment")
|
||||
.Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization(null, options =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder("Bearer").RequiresClaim("Permission", "CanViewComment");
|
||||
options.AddPolicy("CanViewComment", policy.Build());
|
||||
});
|
||||
services.AddAuthorization();
|
||||
services.AddTransient<IAuthorizationHandler, DenyAnonymousAuthorizationHandler>();
|
||||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(authorizationContext.Result);
|
||||
|
|
@ -263,30 +262,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
public async Task Invoke_CanLookingForClaimsInMultipleIdentities()
|
||||
{
|
||||
// Arrange
|
||||
var authorizeAttribute = new AuthorizeAttribute("CanViewCommentCupBearer");
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization(null, options =>
|
||||
{
|
||||
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 authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder("Basic", "Bearer")
|
||||
.RequiresClaim("Permission", "CanViewComment")
|
||||
.RequiresClaim("Permission", "CupBearer")
|
||||
.Build());
|
||||
var authorizationContext = GetAuthorizationContext(services =>
|
||||
{
|
||||
services.AddAuthorization();
|
||||
|
|
@ -294,10 +273,80 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
await authorizeAttribute.OnAuthorizationAsync(authorizationContext);
|
||||
await authorizeFilter.OnAuthorizationAsync(authorizationContext);
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanAuthorizeParticularUsers()
|
||||
|
||||
[Theory]
|
||||
[InlineData("AdminRole")]
|
||||
[InlineData("InteractiveUsers")]
|
||||
[InlineData("ApiManagers")]
|
||||
public async Task CanAuthorize(string testAction)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
|
|
@ -115,7 +119,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
// Act
|
||||
var response = await client.GetAsync(
|
||||
"http://localhost/AuthorizeUser/ReturnHelloWorldOnlyForAuthorizedUser");
|
||||
"http://localhost/AuthorizeUser/"+testAction);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
|
|
|||
|
|
@ -372,8 +372,9 @@ namespace System.Web.Http
|
|||
var assemblyProvider = new FixedSetAssemblyProvider();
|
||||
assemblyProvider.CandidateAssemblies.Add(GetType().GetTypeInfo().Assembly);
|
||||
var controllerTypeProvider = new NamespaceFilteredControllerTypeProvider(assemblyProvider);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(),
|
||||
NullLoggerFactory.Instance);
|
||||
var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
|
||||
NullLoggerFactory.Instance,
|
||||
null);
|
||||
|
||||
var filterProvider = new Mock<IGlobalFilterProvider>();
|
||||
filterProvider
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http.Security;
|
||||
using Microsoft.AspNet.Security;
|
||||
|
|
@ -11,51 +12,21 @@ using Microsoft.Framework.OptionsModel;
|
|||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class BasicOptions : AuthenticationOptions
|
||||
{
|
||||
public BasicOptions()
|
||||
{
|
||||
AuthenticationType = "Basic";
|
||||
AuthenticationMode = AuthenticationMode.Passive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AuthorizeBasicMiddleware : AuthenticationMiddleware<BasicOptions>
|
||||
{
|
||||
public AuthorizeBasicMiddleware(
|
||||
RequestDelegate next,
|
||||
IServiceProvider services,
|
||||
IOptions<BasicOptions> options) :
|
||||
base(next, services, options, null)
|
||||
{ }
|
||||
IOptions<BasicOptions> options,
|
||||
string authType) :
|
||||
base(next, services, options,
|
||||
new ConfigureOptions<BasicOptions>(o => o.AuthenticationType = authType) { Name = authType })
|
||||
{
|
||||
}
|
||||
|
||||
protected override AuthenticationHandler<BasicOptions> CreateHandler()
|
||||
{
|
||||
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.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Security;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[AuthorizeUser]
|
||||
[Authorize("RequireBasic")]
|
||||
[Authorize("Api")]
|
||||
public class AuthorizeUserController : Controller
|
||||
{
|
||||
[Authorize("CanViewPage")]
|
||||
public string ReturnHelloWorldOnlyForAuthorizedUser()
|
||||
[Authorize("Api-Manager")]
|
||||
public string ApiManagers()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
[Authorize(Roles = "Administrator")]
|
||||
public string AdminRole()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
[Authorize("Interactive")]
|
||||
public string InteractiveUsers()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
|
|
@ -27,6 +39,5 @@ namespace FiltersWebSite
|
|||
{
|
||||
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.
|
||||
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Security;
|
||||
|
|
@ -18,23 +19,32 @@ namespace FiltersWebSite
|
|||
app.UseServices(services =>
|
||||
{
|
||||
services.AddMvc(configuration);
|
||||
services.Configure<AuthorizationOptions>(options =>
|
||||
services.ConfigureAuthorization(options =>
|
||||
{
|
||||
// This policy cannot succeed since it has no requirements
|
||||
options.AddPolicy("Impossible",
|
||||
new AuthorizationPolicyBuilder()
|
||||
.Build());
|
||||
options.AddPolicy("RequireBasic",
|
||||
new AuthorizationPolicyBuilder("Basic")
|
||||
.RequiresClaim(ClaimTypes.NameIdentifier)
|
||||
.Build());
|
||||
options.AddPolicy("CanViewPage",
|
||||
new AuthorizationPolicyBuilder()
|
||||
.RequiresClaim("Permission", "CanViewPage")
|
||||
.Build());
|
||||
options.AddPolicy("Impossible", policy => { });
|
||||
options.AddPolicy("Api", policy =>
|
||||
{
|
||||
policy.ActiveAuthenticationTypes.Add("Api");
|
||||
policy.RequiresClaim(ClaimTypes.NameIdentifier);
|
||||
});
|
||||
options.AddPolicy("Api-Manager", policy =>
|
||||
{
|
||||
policy.ActiveAuthenticationTypes.Add("Api");
|
||||
policy.Requirements.Add(Operations.Edit);
|
||||
});
|
||||
options.AddPolicy("Interactive", policy =>
|
||||
{
|
||||
policy.ActiveAuthenticationTypes.Add("Interactive");
|
||||
policy.RequiresClaim(ClaimTypes.NameIdentifier)
|
||||
.RequiresClaim("Permission", "CanViewPage");
|
||||
});
|
||||
});
|
||||
services.AddSingleton<RandomNumberFilter>();
|
||||
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 =>
|
||||
{
|
||||
|
|
@ -48,7 +58,8 @@ namespace FiltersWebSite
|
|||
|
||||
app.UseErrorReporter();
|
||||
|
||||
app.UseMiddleware<AuthorizeBasicMiddleware>();
|
||||
app.UseMiddleware<AuthorizeBasicMiddleware>("Interactive");
|
||||
app.UseMiddleware<AuthorizeBasicMiddleware>("Api");
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue