sammarcow
sammarcow

Reputation: 2956

AllowAnyonmous attribute not honored in IAuthorizationFilter in .net core web api

I have a new Web API built with .net Core with a custom authorization filter. I need to bypass this filter for a handful of actions but otherwise require it globally. How do I get MyAuthFilter to honor the [Microsoft.AspNetCore.Authorization] attribute on method UserController.Post?

Authorization Filter:

public class MyAuthFilter : IAuthorizationFilter {
    public void OnAuthorization(AuthorizationFilterContext context) {
        //do some auth 
    }
}

Registration of Auth filter globally in Startup.cs:

public void ConfigureServices(IServiceCollection services) {
    services.AddMvc(options => {
        options.Filters.Add(new MyAuthFilter());
    });
}

Attribute decoration on user controller:

[Route("api/[controller]")]
[Authorize] //only want anonymous on single action within controller
public class UserController { 

    [HttpPost("login")]
    [AllowAnonymous] //this is not honored - MyAuthFilter.OnAuthorization is executed
        public JObject Post([FromBody] JObject userLogin) {

        }
}

Upvotes: 4

Views: 2161

Answers (3)

Hazza
Hazza

Reputation: 6591

For .net core 3.1 you can check for IAllowAnonymous on the endpoint.

// context is AuthorizationFilterContext
var endpoint = context.HttpContext.GetEndpoint();
if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
{
    // do stuff
}

This change is explained in the update notes found here.

Upvotes: 4

John Tolar
John Tolar

Reputation: 357

For anyone looking regarding .Net (Core) 5.0 this can be done by looking at the ActionDescriptors EndpointMetaData.

if (context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any())
            return;

Upvotes: 7

Chris Pratt
Chris Pratt

Reputation: 239440

The built-in AuthorizeFilter has the following lines:

// Allow Anonymous skips all authorization
if (context.Filters.Any(item => item is IAllowAnonymousFilter))
{
    return;
}

FWIW, when you're building your own implementations for these types of things, you need to be careful that your implementation accounts for everything it should. If you look at the source code for AuthorizeFilter, you'll see it does quite a bit that yours likely isn't. Often, it's better to simply derive from the built-in implementation and override as necessary, rather than attempting to implement the interface yourself.

Upvotes: 6

Related Questions