Action filters & Authorization Filters working
This commit is contained in:
parent
6fed92695b
commit
772f833dc9
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace MvcSample.Filters
|
||||
{
|
||||
public class AgeEnhancerAttribute : ActionFilterAttribute
|
||||
{
|
||||
public async override Task Invoke(ActionFilterContext context, Func<Task> next)
|
||||
{
|
||||
object age = null;
|
||||
|
||||
if (context.ActionParameters.TryGetValue("age", out age))
|
||||
{
|
||||
if (age is int)
|
||||
{
|
||||
var intAge = (int) age;
|
||||
|
||||
if (intAge < 21)
|
||||
{
|
||||
intAge += 5;
|
||||
}
|
||||
else if (intAge > 30)
|
||||
{
|
||||
intAge = 29;
|
||||
}
|
||||
|
||||
context.ActionParameters["age"] = intAge;
|
||||
}
|
||||
}
|
||||
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace MvcSample
|
||||
{
|
||||
public class PassThroughAttribute : AuthorizationFilterAttribute
|
||||
{
|
||||
public async override Task Invoke(AuthorizationFilterContext context, Func<Task> next)
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using MvcSample.Filters;
|
||||
using MvcSample.Models;
|
||||
|
||||
namespace MvcSample
|
||||
{
|
||||
// Expected order in descriptor - object -> int -> string
|
||||
// TODO: Add a real filter here
|
||||
[ServiceFilter(typeof(object), Order = 1)]
|
||||
[ServiceFilter(typeof(string))]
|
||||
[ServiceFilter(typeof(PassThroughAttribute), Order = 1)]
|
||||
[ServiceFilter(typeof(PassThroughAttribute))]
|
||||
[PassThrough(Order = 0)]
|
||||
[PassThrough(Order = 2)]
|
||||
public class FiltersController : Controller
|
||||
|
|
@ -16,18 +15,13 @@ namespace MvcSample
|
|||
private readonly User _user = new User() { Name = "User Name", Address = "Home Address" };
|
||||
|
||||
// TODO: Add a real filter here
|
||||
[ServiceFilter(typeof(int))]
|
||||
public IActionResult Index()
|
||||
[ServiceFilter(typeof(PassThroughAttribute))]
|
||||
[AgeEnhancer]
|
||||
public IActionResult Index(int age)
|
||||
{
|
||||
_user.Age = age;
|
||||
|
||||
return View("MyView", _user);
|
||||
}
|
||||
}
|
||||
|
||||
public class PassThroughAttribute : AuthorizationFilterAttribute
|
||||
{
|
||||
public async override Task Invoke(AuthorizationFilterContext context, Func<Task> next)
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,5 +4,6 @@
|
|||
{
|
||||
public string Name { get; set; }
|
||||
public string Address { get; set; }
|
||||
public int Age { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,8 @@ namespace MvcSample
|
|||
var services = MvcServices.GetDefaultServices(configuration, _env);
|
||||
var serviceProvider = new ServiceProvider().Add(services);
|
||||
|
||||
serviceProvider.AddInstance<PassThroughAttribute>(new PassThroughAttribute());
|
||||
|
||||
var routes = new RouteCollection()
|
||||
{
|
||||
DefaultHandler = new MvcApplication(serviceProvider),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more »</a></p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3 title="@Model.Name" class="@nullValue">Hello @Model.Name!</h3>
|
||||
<h3 title="@Model.Name" class="@nullValue">Hello @Model.Name! Happy @Model.Age birthday.</h3>
|
||||
|
||||
<div class="col-md-4">
|
||||
<h2>Getting started</h2>
|
||||
|
|
@ -5,10 +5,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class ActionFilterContext
|
||||
{
|
||||
public ActionFilterContext(ActionContext actionContext, IDictionary<string, object> actionParameters)
|
||||
public ActionFilterContext(ActionContext actionContext,
|
||||
IDictionary<string, object> actionParameters,
|
||||
Type methodReturnType)
|
||||
{
|
||||
ActionContext = actionContext;
|
||||
ActionParameters = actionParameters;
|
||||
MethodReturnType = methodReturnType;
|
||||
}
|
||||
|
||||
public virtual IDictionary<string, object> ActionParameters { get; private set; }
|
||||
|
|
@ -17,6 +20,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public virtual Type MethodReturnType { get; private set; }
|
||||
|
||||
public virtual object Result { get; set; }
|
||||
public virtual IActionResult Result { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
var controllerAttributes = cd.ControllerTypeInfo.GetCustomAttributes(inherit: true).ToArray();
|
||||
var filtersFromController = GetOrderedFilterAttributes(controllerAttributes);
|
||||
|
||||
bool allowAnonymous = IsAnonymous(controllerAttributes);
|
||||
|
||||
|
||||
bool allowAnonymous = IsAnonymous(controllerAttributes);
|
||||
|
||||
foreach (var methodInfo in cd.ControllerTypeInfo.DeclaredMethods)
|
||||
|
|
|
|||
|
|
@ -66,21 +66,40 @@ namespace Microsoft.AspNet.Mvc
|
|||
var parameterValues = await GetParameterValues(modelState);
|
||||
|
||||
var authZFilters = context.AuthorizationFilters;
|
||||
var authZEndPoint = new AuthorizationFilterEndPoint();
|
||||
authZFilters.Add(authZEndPoint);
|
||||
var authZContext = new AuthorizationFilterContext(_actionContext);
|
||||
var authZPipeline = new FilterPipelineBuilder<AuthorizationFilterContext>(authZFilters, authZContext);
|
||||
|
||||
await authZPipeline.InvokeAsync();
|
||||
|
||||
|
||||
if (authZContext.ActionResult == null &&
|
||||
!authZContext.HasFailed &&
|
||||
authZEndPoint.EndPointCalled)
|
||||
bool authZPassed;
|
||||
if (authZFilters != null && authZFilters.Count > 0)
|
||||
{
|
||||
var actionFilters = context.ActionFilters;
|
||||
var authZEndPoint = new AuthorizationFilterEndPoint();
|
||||
authZFilters.Add(authZEndPoint);
|
||||
var authZContext = new AuthorizationFilterContext(_actionContext);
|
||||
var authZPipeline = new FilterPipelineBuilder<AuthorizationFilterContext>(authZFilters,
|
||||
authZContext);
|
||||
|
||||
await authZPipeline.InvokeAsync();
|
||||
|
||||
if (authZContext.ActionResult == null &&
|
||||
!authZContext.HasFailed &&
|
||||
authZEndPoint.EndPointCalled)
|
||||
{
|
||||
actionResult = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
actionResult = authZContext.ActionResult ?? new HttpStatusCodeResult(401);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actionResult = null;
|
||||
}
|
||||
|
||||
if (actionResult == null)
|
||||
{
|
||||
var actionFilters = context.ActionFilters ?? new List<IActionFilter>();
|
||||
var actionFilterContext = new ActionFilterContext(_actionContext,
|
||||
new Dictionary<string, object>());
|
||||
parameterValues,
|
||||
method.ReturnType);
|
||||
|
||||
// TODO: This is extremely temporary and is going to get soon replaced with the action executer
|
||||
var actionEndPoint = new ReflectedActionFilterEndPoint(async (inArray) => method.Invoke(controller, inArray),
|
||||
|
|
@ -93,18 +112,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
await actionFilterPipeline.InvokeAsync();
|
||||
|
||||
object actionReturnValue = method.Invoke(controller, null);
|
||||
actionResult = _actionResultFactory.CreateActionResult(method.ReturnType, actionReturnValue, _actionContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionResult = authZContext.ActionResult ?? new HttpStatusCodeResult(401);
|
||||
actionResult = (IActionResult)actionFilterContext.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var actionResultFilters = context.ActionResultFilters;
|
||||
await actionResult.ExecuteResultAsync(_actionContext);
|
||||
var actionResultFilters = context.ActionResultFilters ?? new List<IActionResultFilter>();
|
||||
var actionResultFilterContext = new ActionResultFilterContext(_actionContext, actionResult);
|
||||
var actionResultFilterEndPoint = new ActionResultFilterEndPoint();
|
||||
actionResultFilters.Add(actionResultFilterEndPoint);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
yield return DescribeService<INestedProvider<ActionDescriptorProviderContext>,
|
||||
ReflectedActionDescriptorProvider>(configuration);
|
||||
yield return DescribeService<INestedProvider<ActionInvokerProviderContext>,
|
||||
ActionInvokerProvider>(configuration);
|
||||
ReflectedActionInvokerProvider>(configuration);
|
||||
|
||||
yield return DescribeService<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>(configuration);
|
||||
yield return DescribeService<IActionBindingContextProvider, DefaultActionBindingContextProvider>(configuration);
|
||||
|
|
|
|||
Loading…
Reference in New Issue