Фильтр аутентификации не работает с фильтром авторизации в Web API

#c# #asp.net #asp.net-web-api #asp.net-web-api-filters

#c# #asp.net #asp.net-web-api #asp.net-web-api-filters

Вопрос:

Я пытаюсь создать пользовательский фильтр аутентификации для ASP.NET Веб-API. Ниже приведен код для моего фильтра аутентификации

 public class IDPAuthenticationFilter : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var identity = new ClaimsIdentity();
        identity.AddClaim(new Claim(ClaimTypes.Name, "testUser"));
        identity.AddClaim(new Claim(ClaimTypes.Role, "client"));
        identity.AddClaim(new Claim("testUser"));
        identity.AddClaim(new Claim("APP:USERID", "50123"));

        var principal = new GenericPrincipal(identity, new string[] { });
        Thread.CurrentPrincipal = principal;
        HttpContext.Current.User = principal;

        base.OnAuthorization(actionContext);
    }
}
  

Я настроил фильтр аутентификации глобально и подтвердил с помощью контрольной точки, что фильтр вызывается.

 config.Filters.Add(new IDPAuthenticationFilter());
  

Проблема в том, что если я добавлю [System.Web.Http.Authorize] атрибут к любому контроллеру, то получу ошибку 401 Unauthorized. Я могу получить доступ к имени пользователя, используя User.Identity.Name в действии контроллера, но если я добавлю атрибут авторизации, я получу сообщение об ошибке. Есть ли что-то, чего мне не хватает.

Спасибо, что уделили вам время. Пожалуйста, добавьте комментарий на случай, если потребуется какая-либо другая информация.

Комментарии:

1. Могу я спросить, зачем вы добавляете атрибут authorize также, как и ваш?

2. IDPAuthenticationFilter предназначен для установки идентификатора, а атрибут авторизации гарантирует, что только аутентифицированные пользователи могут получить доступ к контроллеру.

3. @cl0ud В Web API фильтры аутентификации обрабатывают аутентификацию, но не авторизацию. Авторизация должна выполняться с помощью фильтра авторизации или внутри действия контроллера.

4. Причина, по которой я спрашиваю, заключается в том, что вы создаете, IDPAuthenticationFilter который наследуется от AuthorizationFilterAttribute . Для меня это в принципе уже звучит некорректно, AuthorizationFilters предназначены для авторизации, как и следует из их названия.

5. Спасибо, что указали на это, я внес некоторые изменения, и теперь я внедряю IAuthenticationFilter. При необходимости обновит вопрос.

Ответ №1:

Было несколько вещей, которые я делал неправильно. Сначала мне нужно было реализовать IAuthenticationFilter вместо AuthorizationFilterAttribute

Во-вторых, способ, которым я устанавливал идентификатор, был неправильным. Ниже приведен код, который сработал у меня.

 public class IDPAuthenticationFilter : Attribute, IAuthenticationFilter 
{

    public bool AllowMultiple => false;

    public async Task AuthenticateAsync (HttpAuthenticationContext context, CancellationToken cancellationToken) 
    {

        HttpRequestMessage request = context.Request;
        AuthenticationHeaderValue authorization = request.Headers.Authorization;

        if (authorization == null) {
            return;
        }
        if (authorization.Scheme != "Bearer") {
            return;
        }

        var claims = new List<Claim> ();
        claims.Add (new Claim (ClaimTypes.Name, "testUser"));
        claims.Add (new Claim (ClaimTypes.Role, "client"));
        claims.Add (new Claim ("sub", "testUser"));
        claims.Add (new Claim("APP:USERID", "50123"));

        var identity = new ClaimsIdentity (claims, "Auth_Key");

        var principal = new ClaimsPrincipal (new [] { identity });
        context.Principal = principal;
        HttpContext.Current.User = context.Principal;
        Thread.CurrentPrincipal = context.Principal;

    }

}