I have a controller which should only request authorization when loaded with specific parameters. Like when the parameter ID is 8 for example.
I came up with using a custom validation attribute like this:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (/* Action's inputparameter ID = 8 */)
{
return base.AuthorizeCore(httpContext);
}
return true;
}
}
My action looks like this (not that it is interesting)
[MyAuthorize]
public ActionResult Protected(int id)
{
/* custom logic for setting the viewmodel from the id parameter */
return View(viewmodel);
}
The problem is as you can see that I don't know how to check for that ID parameter in the authorize attribute.
Can you help me with a solution?
If the id is passed as request parameter (GET or POST) or as a route data parameter:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// first look at routedata then at request parameter:
var id = (httpContext.Request.RequestContext.RouteData.Values["id"] as string)
??
(httpContext.Request["id"] as string);
if (id == "8")
{
return base.AuthorizeCore(httpContext);
}
return true;
}
As long as AuthorizeAttribute
is being inherited, you can get your parameter from AuthorizationContext
, as follows:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
string idParam = filterContext.Controller.ValueProvider.GetValue("id").AttemptedValue;
int id;
if (int.TryParse(idParam, out id))
{
if (id == 8) // apply your business logic here
return;
}
filterContext.Result = new HttpUnauthorizedResult();
}
}
[MyAuthorize]
public ActionResult Protected(int id)
{
return View();
}
The ValueProvider
will iterate through all registered providers that by default includes RouteDataValueProvider
, QueryStringValueProvider
and FormValueProvider
, and do all the work for you.
Otherwise I recommend using ActionFilterAttribute
.
You need something like this.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
int? id = GetId(filterContext);
if (id.HasValue)
{
...
}
}
private static int? GetId(ActionExecutingContext filterContext)
{
int? Id = null;
if (filterContext.ActionParameters.ContainsKey("Id"))
{
Id = (int?)filterContext.ActionParameters["Id"];
}
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var rd = httpContext.Request.RequestContext.RouteData;
string currentAction = rd.GetRequiredString("action");
string actionparam =Convert.ToString(rd.Values["param"]);
if (id == actionparam)
{
return base.AuthorizeCore(httpContext);
}
return true;
}