/// <summary> /// This method will go an execute the authorization filters for the controller action, if any fail /// it will return their response, otherwise we'll return null. /// </summary> /// <param name="controllerContext"></param> internal static async Task <HttpResponseMessage> InvokeAuthorizationFiltersForRequest(this HttpControllerContext controllerContext) { var controllerDescriptor = controllerContext.ControllerDescriptor; var controllerServices = controllerDescriptor.Configuration.Services; var actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext); var actionContext = new HttpActionContext(controllerContext, actionDescriptor); var filters = actionDescriptor.GetFilterPipeline(); var filterGrouping = new FilterGrouping(filters); var actionFilters = filterGrouping.ActionFilters; // Because the continuation gets built from the inside out we need to reverse the filter list // so that least specific filters (Global) get run first and the most specific filters (Action) get run last. var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToArray(); if (authorizationFilters.Any()) { var cancelToken = new CancellationToken(); var filterResult = await FilterContinuation(actionContext, cancelToken, authorizationFilters, 0); if (filterResult != null) { //this means that the authorization filter has returned a result - unauthorized so we cannot continue return(filterResult); } } return(null); }
/// <summary> /// This method will go an execute the authorization filters for the controller action, if any fail /// it will return their response, otherwise we'll return null. /// </summary> /// <param name="controllerContext"></param> internal static async Task<HttpResponseMessage> InvokeAuthorizationFiltersForRequest(this HttpControllerContext controllerContext) { var controllerDescriptor = controllerContext.ControllerDescriptor; var controllerServices = controllerDescriptor.Configuration.Services; var actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext); var actionContext = new HttpActionContext(controllerContext, actionDescriptor); var filters = actionDescriptor.GetFilterPipeline(); var filterGrouping = new FilterGrouping(filters); var actionFilters = filterGrouping.ActionFilters; // Because the continuation gets built from the inside out we need to reverse the filter list // so that least specific filters (Global) get run first and the most specific filters (Action) get run last. var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToArray(); if (authorizationFilters.Any()) { var cancelToken = new CancellationToken(); var filterResult = await FilterContinuation(actionContext, cancelToken, authorizationFilters, 0); if (filterResult != null) { //this means that the authorization filter has returned a result - unauthorized so we cannot continue return filterResult; } } return null; }
public virtual Task <HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) { if (_initialized) { // if user has registered a controller factory which produces the same controller instance, we should throw here throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name); } Initialize(controllerContext); // We can't be reused, and we know we're disposable, so make sure we go away when // the request has been completed. if (Request != null) { Request.RegisterForDispose(this); } HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor; ServicesContainer controllerServices = controllerDescriptor.Configuration.Services; HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext); ActionContext.ActionDescriptor = actionDescriptor; if (Request != null) { Request.SetActionDescriptor(actionDescriptor); } FilterGrouping filterGrouping = actionDescriptor.GetFilterGrouping(); IActionFilter[] actionFilters = filterGrouping.ActionFilters; IAuthenticationFilter[] authenticationFilters = filterGrouping.AuthenticationFilters; IAuthorizationFilter[] authorizationFilters = filterGrouping.AuthorizationFilters; IExceptionFilter[] exceptionFilters = filterGrouping.ExceptionFilters; IHttpActionResult result = new ActionFilterResult(actionDescriptor.ActionBinding, ActionContext, controllerServices, actionFilters); if (authorizationFilters.Length > 0) { result = new AuthorizationFilterResult(ActionContext, authorizationFilters, result); } if (authenticationFilters.Length > 0) { result = new AuthenticationFilterResult(ActionContext, this, authenticationFilters, result); } if (exceptionFilters.Length > 0) { IExceptionLogger exceptionLogger = ExceptionServices.GetLogger(controllerServices); IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(controllerServices); result = new ExceptionFilterResult(ActionContext, exceptionFilters, exceptionLogger, exceptionHandler, result); } return(result.ExecuteAsync(cancellationToken)); }
/// <summary> /// Invokes the authorization filters for the controller action. /// </summary> /// <returns>Whether the user is authenticated or not.</returns> internal static async Task <bool> InvokeAuthorizationFiltersForRequest(this ControllerContext controllerContext, ActionContext actionContext) { ControllerActionDescriptor actionDescriptor = controllerContext.ActionDescriptor; var metadataCollection = new EndpointMetadataCollection(actionDescriptor.EndpointMetadata.Union(new[] { actionDescriptor })); IReadOnlyList <IAuthorizeData> authorizeData = metadataCollection.GetOrderedMetadata <IAuthorizeData>(); IAuthorizationPolicyProvider policyProvider = controllerContext.HttpContext.RequestServices .GetRequiredService <IAuthorizationPolicyProvider>(); AuthorizationPolicy?policy = await AuthorizationPolicy.CombineAsync(policyProvider, authorizeData); if (policy is not null) { IPolicyEvaluator policyEvaluator = controllerContext.HttpContext.RequestServices.GetRequiredService <IPolicyEvaluator>(); AuthenticateResult authenticateResult = await policyEvaluator.AuthenticateAsync(policy, controllerContext.HttpContext); if (!authenticateResult.Succeeded) { return(false); } // TODO this is super hacky, but we rely on the FeatureAuthorizeHandler can still handle endpoints // (The way before .NET 5). The .NET 5 way would need to use han http context, for the "inner" request // with the nested controller var resource = new Endpoint(null, metadataCollection, null); PolicyAuthorizationResult authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, controllerContext.HttpContext, resource); if (!authorizeResult.Succeeded) { return(false); } } IList <FilterDescriptor> filters = actionDescriptor.FilterDescriptors; var filterGrouping = new FilterGrouping(filters, controllerContext.HttpContext.RequestServices); // because the continuation gets built from the inside out we need to reverse the filter list // so that least specific filters (Global) get run first and the most specific filters (Action) get run last. var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToList(); var asyncAuthorizationFilters = filterGrouping.AsyncAuthorizationFilters.Reverse().ToList(); if (authorizationFilters.Count == 0 && asyncAuthorizationFilters.Count == 0) { return(true); } // if the authorization filter returns a result, it means it failed to authorize var authorizationFilterContext = new AuthorizationFilterContext(actionContext, filters.Select(x => x.Filter).ToArray()); return(await ExecuteAuthorizationFiltersAsync(authorizationFilterContext, authorizationFilters, asyncAuthorizationFilters)); }
public void GetDeliveries_LightWeightsSelector_ultipleParcelsTwoRecipients_ReturnsSizeTwoList() { // Arrange var selector = new FilterGrouping(MultipleParcelsTwoRecipients); // Act var selectedItems = selector.GetDeliveries().ToList(); // Assert Assert.AreEqual(selectedItems.Count(), 2); }
public void GetDeliveries_FilterGrouping_MultipleParcelsOneRecipients_ReturnsSizeOneList() { // Arrange var selector = new FilterGrouping(MultipleParcelsOneRecipients); // Act var selectedItems = selector.GetDeliveries().ToList(); // Assert Assert.AreEqual(selectedItems.Count(), 1); Assert.AreEqual(selectedItems[0].weight, 105); Assert.AreEqual(selectedItems[0].value, 1501); }
public virtual Task <HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) { if (_request != null) { // if user has registered a controller factory which produces the same controller instance, we should throw here throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name); } Initialize(controllerContext); // We can't be reused, and we know we're disposable, so make sure we go away when // the request has been completed. if (_request != null) { _request.RegisterForDispose(this); } HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor; ServicesContainer controllerServices = controllerDescriptor.Configuration.Services; HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); IEnumerable <FilterInfo> filters = actionDescriptor.GetFilterPipeline(); FilterGrouping filterGrouping = new FilterGrouping(filters); IEnumerable <IActionFilter> actionFilters = filterGrouping.ActionFilters; IEnumerable <IAuthorizationFilter> authorizationFilters = filterGrouping.AuthorizationFilters; IEnumerable <IExceptionFilter> exceptionFilters = filterGrouping.ExceptionFilters; // Func<Task<HttpResponseMessage>> Task <HttpResponseMessage> result = InvokeActionWithAuthorizationFilters(actionContext, cancellationToken, authorizationFilters, () => { HttpActionBinding actionBinding = actionDescriptor.ActionBinding; Task bindTask = actionBinding.ExecuteBindingAsync(actionContext, cancellationToken); return(bindTask.Then <HttpResponseMessage>(() => { _modelState = actionContext.ModelState; Func <Task <HttpResponseMessage> > invokeFunc = InvokeActionWithActionFilters(actionContext, cancellationToken, actionFilters, () => { return controllerServices.GetActionInvoker().InvokeActionAsync(actionContext, cancellationToken); }); return invokeFunc(); })); })(); result = InvokeActionWithExceptionFilters(result, actionContext, cancellationToken, exceptionFilters); return(result); }
/// <summary> /// Invokes the authorization filters for the controller action. /// </summary> /// <returns>The response of the first filter returning a result, if any, otherwise null (authorized).</returns> internal static async Task <HttpResponseMessage> InvokeAuthorizationFiltersForRequest(this HttpControllerContext controllerContext) { var controllerDescriptor = controllerContext.ControllerDescriptor; var controllerServices = controllerDescriptor.Configuration.Services; var actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext); var filters = actionDescriptor.GetFilterPipeline(); var filterGrouping = new FilterGrouping(filters); // because the continuation gets built from the inside out we need to reverse the filter list // so that least specific filters (Global) get run first and the most specific filters (Action) get run last. var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToList(); if (authorizationFilters.Count == 0) { return(null); } // if the authorization filter returns a result, it means it failed to authorize var actionContext = new HttpActionContext(controllerContext, actionDescriptor); return(await ExecuteAuthorizationFiltersAsync(actionContext, CancellationToken.None, authorizationFilters)); }