pg2727
pg2727

Reputation: 179

Web API Controller Authorization with parameters

I have a MVC5 applicatino where we use mvc controllers AND web api controllers.

We have authorization attributes on our MVC Controller as like this:

    /// <summary>
    /// Only allows authorization if the logged in user has the corresponding application access name
    /// </summary>
    /// <seealso cref="AuthorizeAttribute" />
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class ApplicationAccessAuthorizationAttribute : AuthorizationBaseAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ApplicationAccessAuthorizationAttribute"/> class.
        /// </summary>
        /// <param name="accessNames">Name of the access.</param>
        public ApplicationAccessAuthorizationAttribute(string accessNames)
        {
            AccessNames = accessNames.Split(',');
        }

        /// <summary>
        /// Gets or sets a comma separated list of access names to apply against the users
        /// permission set.
        /// </summary>
        protected IList<string> AccessNames { get; set; }

        /// <summary>
        /// Called when a process requests authorization.
        /// </summary>
        /// <param name="filterContext">The filter context, which encapsulates information for using <see cref="T:System.Web.Mvc.AuthorizeAttribute" />.</param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (!filterContext.HttpContext.Request.IsAuthenticated)
            {
                filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary(new { controller = "Account", action = "Login", area = string.Empty, returnURL = HttpContext.Current.Request.RawUrl }));
            }
            else
            {
                     var currentUserId = GetUserId();

                    var userPermissions = Task.Run(() => UserService.GetUsersApplicationAccess(currentUserId)).Result;
                    var permissions = userPermissions.Select(x => x.AccessName).ToList();

                    if (!permissions.Intersect(AccessNames).Any())
                    {
                        filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary(new { controller = "Error", action = "NotFound", area = string.Empty }));
                    }
            }
        }
    }

Then we call it like this:

    [ApplicationAccessAuthorization(ApplicationAccessConstants.Manager)]

I need to duplicate this on a WebAPI Controller.

I know I need to add a filter in WebApiConfig file.

But how do I pass the specific access names that are requested for each controller / action call in the web API controller?

    public static class WebApiConfig
    {
        /// <summary>
        /// Registers the specified configuration.
        /// </summary>
        /// <param name="config">The configuration.</param>
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });

            // Log the filter here for the api controllers error handling ; this should catch all errors that occur within the web api
            config.Filters.Add(new APICustomExceptionFilter();
        }
    }

How can I pass parameters with the API Web Controller set up?

Because when I set my filter in WebAPIConfig file, it is forcing me to add the "AccessNames" as a parameter, but I do no have access to that yet?

Upvotes: 0

Views: 694

Answers (1)

pg2727
pg2727

Reputation: 179

I did not need the WebApiConfig.cs filter. I could leave that out and me changing it from MVC to API Controller attribute appears to have fixed it.

    /// <summary>
    /// Only allows authorization if the logged in user has the corresponding application access name
    /// </summary>
    /// <seealso cref="AuthorizeAttribute" />
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class WebApplicationAccessAuthorizationAttribute : AuthorizationFilterAttribute
...

Upvotes: 1

Related Questions