Web API 2 Basic Authentication и разрешить действия, не отмеченные [Авторизовать] - PullRequest
0 голосов
/ 12 октября 2018

Я изучал базовую аутентификацию в Web Api2 и, похоже, не нашел объяснения тому, что меня смущает.

Я создал проект приложения web api с индивидуальной аутентификацией в Visual studio 2017.

У меня есть код по умолчанию

public class ValuesController : ApiController
{ 
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
     }

    public string Get(int id)
    {
       return "value";
     }
}

Я называю эти действия с помощью почтальона, браузера и т. Д. Все хорошо.

Если я добавлю атрибут [Authorize] к одному изметоды я получаю 401 несанкционированный ответ, как и ожидалось.

Пока все хорошо.

Затем я добавляю базовую аутентификацию, создавая класс, производный от AuthorizationFilterAttribute

public class BasicAuthenticationAttribute : AuthorizationFilterAttribute
{
  public override void OnAuthorization(HttpActionContext actionContext)
  {
    var authHeader = actionContext.Request.Headers.Authorization;

    if (authHeader != null)
    {
      var authenticationToken = actionContext.Request.Headers.Authorization.Parameter;
      var decodedAuthenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationToken));
      var usernamePasswordArray = decodedAuthenticationToken.Split(':');
      var userName = usernamePasswordArray[0];
      var password = usernamePasswordArray[1];

      var isValid = userName == "ade" && password == "password";

      if (isValid)
      {
        var principal = new GenericPrincipal(new GenericIdentity(userName), null);

        HttpContext.Current.User = principal;

        return;
       }
     }
    }

    HandleUnathorized(actionContext);
  }

 private static void HandleUnathorized(HttpActionContext actionContext)
 {
    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
    actionContext.Response.Headers.Add("WWW-Authenticate", "Basic Scheme='Data' location = 'http://localhost:");
 }

Я регистрируюфильтр в WebApiConfig.cs

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

Я использую почтальон для вызова действия, помеченного [Авторизовать] и отправки с заголовком. Авторизация: Базовая YWRlOnBhc3N3b3Jk

Запрос авторизован, и я получаю ответ на мое действие,Все хорошо.

Теперь я вызываю действие, которое не помечено [Authorize] без заголовка авторизации от почтальона, ожидающего получить ответ, но вызывается OnAuthorization и, очевидно, возвращает HandleUnathorized (actionContext);Я ожидал, что метод OnAuthorization будет вызываться только тогда, когда действие помечено [Authorize]

Так что теперь я думаю, в чем смысл атрибута [Authorize], потому что OnAuthorization вызывается независимо от того, в чем смыслпомечать действия [Authorize] атрибут?

Во-вторых, я добавил следующий метод в свой класс

private static bool SkipAuthorization(HttpActionContext actionContext)
    {
        Contract.Assert(actionContext != null);

        return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
                   || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
}

Я вызываю этот метод в начале OnAuthorization

if (SkipAuthorization(actionContext)) return;

Если я отмечу свои действия с помощью [AllowAnonymous], это сработает.

Если на контроллере или в определенных действиях нет атрибута [Authorize], то, конечно, OnAuthorization также следует пропустить?

Я просто не наденуНе вижу смысла в использовании [Авторизовать], я явно что-то здесь упускаю, я делаю что-то не так или мне нужно пометить действия с помощью [AllowAnonymous], чтобы исключить их.

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Если вы используете атрибут [Authorize] и проверку подлинности Windows, тогда авторизация будет выполнена автоматически, вам не нужно выполнять какую-либо специальную настройку, но в любом особом случае, если вам нужно переопределить [Authorize] class, тогда ваш класс подобен приведенному ниже,

  1. Вместо наследования AuthorizationFilterAttribute , вы можете наследовать AuthorizeAttribute

        public class BasicAuthenticationAttribute : AuthorizeAttribute
        {
         //your override methods
        }
    
  2. Вместо использования атрибута [Authorize] используйте имя производного класса.В вашем случае используйте [BasicAuthenticationAttribute] , а не [Authorize]

0 голосов
/ 12 октября 2018

Спасибо, Фрэн, вы выбрали меня на правильном пути.

Я закомментировал следующую строку

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

Я использовал следующие атрибуты в контроллере

public class ValuesController : ApiController
{ 
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    [Authorize]
    [BasicAuthentication]
    public string Get(int id)
    {
        return "value";
    }
}

Если я вызвал действие get (), я получил ответ, OnAuthorisation не было вызвано.Если я вызываю get (int id), я получаю 401 Unauthorized и OnAuthorisation не вызывается.

Я удалил действие [Authorize] из get (int id)

[BasicAuthentication]
public string Get(int id)
{
    return "value";
}

, и все заработало, OnAuthorisation был назван как ожидалось.

...