Search code examples
c#asp.net-web-apiasp.net-web-api2asp.net-web-api-routing

Get Specific Attribute on Route Method from WebAPI Request


I have a Controller which implements an AuthorizableApi Class.

[AttributeUsage(AttributeTargets.Method)]
public class AuthorizableRoute : Attribute { }

public class AuthorizableApi : ApiController
{
    public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
    {
        /* Add functionality here to secure the API */
        return base.ExecuteAsync(controllerContext, cancellationToken);
    }
}

This allows me to secure an entire controller, however I also want to be able secure a single action. Using the controllerContext I can get the controller and route but I don't know if it's possible to get an attribute on that action.

    [HttpPost]
    [AuthorizableRoute]
    public HttpResponseMessage DataAction([FromBody] DataType data)
    {
        /* Actions */
    }

So, I'd like to be able to do something like...

if(Attribute.GetCustomAttribute(myRoute, typeof (AuthorizableRoute)) != null) { }

If this isn't possible then what could be a viable alternative?


Solution

  • You could do this by implementing a Filter. You should however inherit the AuthorizationFilterAttribute and implement the OnAuthorization(HttpActionContext context) method. It should be something like this:

    public class AuthorizableRouteFilterAttribute : AuthorizationFilterAttribute
    {
       public override void OnAuthorization(HttpActionContext context)
       {  
          IPrincipal principal = Thread.CurrentPrincipal;            
          /*Your authorization check here*/
    
          if (!principal.IsInRole("YourRole")) // or whatever check you make
          {
               context.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
               return;
          }
       }        
    }
    
    
    [HttpPost]
    [AuthorizableRouteFilter]
    public HttpResponseMessage DataAction([FromBody] DataType data)
    {
        /* Actions */
    }