Reputation: 1596
I have created a custom authorize attribute class for my application, to test if a user is allowed to access the API route. The user I am testing with has had all permissions that this class will test for removed, however the api is still running. What am I doing wrong?
UserActionsDictionary has tenant IDs as the keys and a list of strings for actions.
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Application {
public class HasActionAttribute : AuthorizeAttribute {
public string Actions { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext) {
UserCache userCache = HELPERS.GetCurrentUserCache();
return userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect(Actions.Split(',').ToList()).Any();
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
filterContext.Result = new HttpUnauthorizedResult("Action not allowed for the current user");
}
}
}
And in the controller. I am testing what should be causing the authorize to fail within the route, it should never even make it in, but with breakpoints I am seeing that test is coming out to false.
[Authorize]
public class TestController : ApiController {
[Route("api/Test/TestRoute")]
[HttpGet]
[HasAction(Actions="Test Action")]
public dynamic Test(){
UserCache userCache = HELPERS.GetCurrentUserCache();
bool test = userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect("Test Action".Split(',').ToList()).Any();
return test;
}
}
I see a lot of questions here on SO about similar topics, but none seem to address the issue I have here.
Upvotes: 0
Views: 291
Reputation: 1596
haim770 answered my issue mostly in the question comments, so I'll put the full answer here for others with similar issues.
I was inheriting the wrong AuthorizeAttribute
. I needed to inherit from System.Web.Http
not System.Web.MVC
. The final code for the attribute is below.
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
namespace Application {
public class HasActionAttribute : AuthorizeAttribute {
public string Actions { get; set; }
public override void OnAuthorization(HttpActionContext actionContext) {
UserCache userCache = HELPERS.GetCurrentUserCache();
List<string> actionsList = Actions.Split(',').Select(a=>a.Trim(' ')).ToList();
if (!userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect(actionsList).Any()) {
HandleUnauthorizedRequest(actionContext);
}
}
protected override void HandleUnauthorizedRequest(HttpActionContext filterContext) {
filterContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden) { Content = new StringContent("Action not allowed for the current user") };
}
}
}
Upvotes: 1
Reputation: 5719
I think that you'd forgotten to put the:
GlobalFilters.Filters.Add(new HasActionAttribute());
in ~/App_Start/FilterConfig.cs
.
The FilterConfig
is used to manage global filters.
UPDATE:
And change you method to check for null parameter:
protected override bool AuthorizeCore(HttpContextBase httpContext) {
if(string.IsNullOrWhiteSpace(Actions))
{
return true;
}
UserCache userCache = HELPERS.GetCurrentUserCache();
return userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect(Actions.Split(',').ToList()).Any();
}
Upvotes: 0