Custom Authorization Filter in .NET Core API

12,463

You should not set the filterContext.Result if the request is successfully authorize.

//
// Summary:
//     A context for authorization filters i.e. Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter
//     and Microsoft.AspNetCore.Mvc.Filters.IAsyncAuthorizationFilter implementations.
public class AuthorizationFilterContext : FilterContext
{
    //
    // Summary:
    //     Gets or sets the result of the request. Setting Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
    //     to a non-null value inside an authorization filter will short-circuit the remainder
    //     of the filter pipeline.
    public virtual IActionResult Result { get; set; }
}

You only need to set Result when it's failed.

public class Authorization: AuthorizeAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext filterContext)
    {
        if (!ValidateToken(filterContext.HttpContext.Request.Headers["token"]))
        {
            filterContext.Result = new UnauthorizedResult();
        }
    }
}
Share:
12,463
Shreyas Pednekar
Author by

Shreyas Pednekar

Updated on June 04, 2022

Comments

  • Shreyas Pednekar
    Shreyas Pednekar almost 2 years

    I want to authorize users before accessing any data using my core api, so I tried is using JWT authentication. I have successfully generated token while signing in user using api and saved that token on client side in session, now whenever user wants to access any data using api, I'll send that token in header to api and I want to validate that JWT token using custom authorization filter. I have created custom authorization filter and applied it on my GetMenu api and I'm able to validate that token successfully but after token validation in authorization filter it is not hitting it on my GetMenu api.

    Here is my AccountController code:

    [Filters.Authorization]
    [AllowAnonymous]
    [HttpPost]
    [Route("GetMenu")]
    public IActionResult GetMenu(string clientid, int rolecode, string repcode)
    {
        //further process
    }
    

    Here is my Filters.Authorization code:

    public class Authorization: AuthorizeAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext filterContext)
        {
            if (!ValidateToken(filterContext.HttpContext.Request.Headers["token"]))
            {
                filterContext.Result = new UnauthorizedResult();
            }
        }
    }
    

    I have breakpoints on OnAuthorization method and on GetMenu api. I'm calling my GetMenu api through postman to test, it is successfully hitting it on OnAuthorization method in Filters.Authorization and validating my JWT Token and displays Status Code: 200 in postman but after successful token validation it should hit on GetMenu api for further data processing but it is not hitting. What can be the issue? what am i missing? please help.

    • Mark Fitzpatrick
      Mark Fitzpatrick about 5 years
      I think it's because you're explicitly setting an OkResult and that's ending processing as it's now returning that result.
    • Shreyas Pednekar
      Shreyas Pednekar about 5 years
      What should I write there?
    • Mark Fitzpatrick
      Mark Fitzpatrick about 5 years
      Have you tried just letting it fall through? If it's not validated you want it to return unauthorized, but if it's ok you want it to just continue going.
    • Shreyas Pednekar
      Shreyas Pednekar about 5 years
      I want to continue this to my api for further data access, but it is not hitting in api after validation
    • Mark Fitzpatrick
      Mark Fitzpatrick about 5 years
      Yes, you're telling it not to. try commenting out the return OkResult. You're literally returning an actionresult right there. You're handling the negative result, which is what primarily matters. If the validation fails you want to kill with an unauthorized result, which you are doing.
    • MrKobayashi
      MrKobayashi about 5 years
      as well as simply returning you could also maybe return a ChallengResult in the event of an anonymous user coming into the app
  • Shreyas Pednekar
    Shreyas Pednekar about 5 years
    I tried your solution now it is giving me Status Code 401 Unauthorized even after filter is validating my token successfully, what can be the issue now?
  • Shreyas Pednekar
    Shreyas Pednekar about 5 years
    I tried setting [AllowAnonymous] on my GetMenu controller now it is hitting on GetMenu after validating token in auth filter, but is this correct way?
  • Edward
    Edward about 5 years
    @ShreyasPednekar Check whether ValidateToken(filterContext.HttpContext.Request.Headers["tok‌​en"]) return true.
  • Shreyas Pednekar
    Shreyas Pednekar about 5 years
    Yes it does return true
  • Edward
    Edward about 5 years
    @ShreyasPednekar Remove [AllowAnonymous] and [Filters.Authorization], will the method be hit?
  • Shreyas Pednekar
    Shreyas Pednekar about 5 years
    Yes it does hit even after removing [AllowAnonymous], but it shows Status 401 Unauthorized
  • Edward
    Edward about 5 years
    @ShreyasPednekar Is there any demo to reproduce your issue?
  • Shreyas Pednekar
    Shreyas Pednekar about 5 years
    Yes if we remove [AllowAnonymous] from GetMenu controller, it will reproduce that issue