2014-11-12 4 views
14

Мое угловое приложение использует токены-носители, как указано в серии статей http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/. Я пошел по раздвоенному примеру, чтобы легко обновлять токены, когда токен доступа истек (через 401 http-код).Определите, истек ли токен-носитель или только что разрешен

Мой вопрос в том, как я могу определить, истек ли токен-носитель или просто несанкционирован в зависимости от определенной роли?

Например, мой метод api в Интернете имеет атрибут [Authorize (Roles = "Admin")]. Когда я звоню на это, я возвращаю свою ошибку 401, которая ожидается. Однако, когда мой токен доступа истекает, и я вызываю другой вызов метода web api, он также возвращает ошибку 401. Heres мой responseError обработчик в моем перехватчика:

 responseError: function (rejection) { 
      var deferred = q.defer(); 
      if (rejection.status === 401) { 
       var authService = $injector.get('authService'); 
       authService.refreshToken().then(function (response) { 
        _retryHttpRequest(rejection.config, deferred); 
       }, function() { 
        authService.logOut(); 
        $location.path('/dashboard'); 
        deferred.reject(rejection); 
       }); 
      } else { 
       deferred.reject(rejection); 
      } 
      return deferred.promise; 
     } 

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

Любые мысли?

+0

Вы должны вернуть 403 Запрещено при ударе по веб-методу api с атрибутом [Авторизовать (Роли = «Администратор»)]. 401 для аутентификации. –

+0

Хммм, после немного большего количества копания, которое я, вероятно, должен был сделать в первую очередь, видимо, атрибут авторизации веб-API всегда будет возвращать 401 неавторизованным как для аутентификации, так и для авторизации. – mmoreno79

ответ

13

Как уже отмечалось в ответе Кори Сильвы, атрибут авторизации Web API всегда возвращает 401 неавторизованным как для аутентификации, так и для авторизации.

См статью и нить ниже:

http://leastprivilege.com/2014/10/02/401-vs-403/

Why does AuthorizeAttribute redirect to the login page for authentication and authorization failures?

Похоже, есть два варианта:

  1. Когда я храню маркер, извлеченный из моего сервера авторизации в localStorage, я также сохраняю срок действия токена. В функции ответа на перехват перехватчика я сравниваю время хранения хранимого токена с текущим временем datetime. Если срок действия истек, обновите токен и отправьте запрос повторно.

    responseError: function (rejection) { 
        var deferred = q.defer(); 
    
        if (rejection.status === 401) { 
         var tokenExpired = false; 
         var authData = localStorage.get('authorizationData'); 
         if (authData) { 
          tokenExpired = moment().isAfter(authData.expiration); 
         } 
    
         if (tokenExpired) { 
          var authService = auth;//$injector.get('authService'); 
          authService.refreshToken().then(function (response) { 
           _retryHttpRequest(rejection.config, deferred); 
          }, function() { 
           authService.logOut(); 
           $state.go('error'); 
           deferred.reject(rejection); 
          }); 
         } 
         else { 
          $state.go('error'); 
          deferred.reject(rejection); 
         } 
        } else { 
         $state.go('error'); 
         deferred.reject(rejection); 
        } 
        return deferred.promise; 
    } 
    
  2. Используйте принятый ответ на StackOverflow нити я, указанной выше, и создать свой собственный AuthorizeAttribute для определения маркеров истечения срока действия против несанкционированного доступа.

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
    public class AuthorizeAttribute : System.Web.Http.AuthorizeAttribute 
    { 
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) 
        { 
         if (actionContext.RequestContext.Principal.Identity.IsAuthenticated) 
         { 
          actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden); 
         } 
         else 
         { 
          base.HandleUnauthorizedRequest(actionContext); 
         } 
        } 
    } 
    

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

+0

Я бы использовал второй вариант. Первый вариант зависит от времени компьютера пользователя, поэтому, если пользователь меняет время, это приведет к неправильному поведению. –