Атрибут AllowAnyonmous не учитывается в IAuthorizationFilter в веб-API .net core

У меня есть новый веб-API, созданный с помощью .net Core с настраиваемым фильтром авторизации. Мне нужно обойти этот фильтр для нескольких действий, но в остальном он требуется глобально. Как заставить MyAuthFilter учитывать атрибут [Microsoft.AspNetCore.Authorization] в методе UserController.Post?

Фильтр авторизации:

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

Глобальная регистрация Auth filter в Startup.cs:

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

Оформление атрибутов на пользовательском контроллере:

[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) {

        }
}

person sammarcow    schedule 26.10.2017    source источник
comment
По логике, это было бы что-то в реализации вашего пользовательского фильтра авторизации, который вы забыли включить.   -  person Chris Pratt    schedule 26.10.2017
comment
@ChrisPratt Вы не можете получить доступ к настраиваемым атрибутам в контексте пользовательского фильтра аутентификации. ActionDescriptor без использования System.Net.Reflection   -  person sammarcow    schedule 26.10.2017
comment
Кто сказал, что нужно? Вся фильтрующая часть этого заключается в том, что это конвейер. Что-то в вашем пользовательском фильтре нарушает этот конвейер, так что дальнейшие шаги не вызываются.   -  person Chris Pratt    schedule 26.10.2017
comment
Да, но мне нужно знать, какой дескриптор действия вызывается, если я выполняю это в фильтре авторизации — вы предлагаете делать это исключительно на основе имени контроллера и метода?   -  person sammarcow    schedule 26.10.2017


Ответы (3)



Для тех, кто интересуется .Net (Core) 5.0, это можно сделать, посмотрев EndpointMetaData ActionDescriptors.

if (context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any())
            return;
person John Tolar    schedule 19.02.2021

Для .net core 3.1 вы можете проверить IAllowAnonymous на конечной точке.

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

Это изменение объясняется в примечаниях к обновлению, найденных здесь.

person Hazza    schedule 15.03.2021