Определите, истек ли срок действия токена на предъявителя или он просто авторизован
мое угловое приложение использует токены на предъявителя, как описано в серии статейhttp://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ - ... Я следовал примеру forked, чтобы легко обновлять токены, когда токен доступа истек (через http-код 401).
мой вопрос: как я могу определить, истек ли токен носителя или просто неавторизован на основе определенной роли?
для например, мой метод web api имеет атрибут [Authorize (Roles="Admin")]. Когда я делаю вызов этому, я возвращаю свою ошибку 401, которая ожидается. Однако, когда мой токен доступа истекает, и я делаю другой вызов метода Web api, он также возвращает ошибку 401. Вот мой обработчик 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;
}
Я играл с разными вещами, но в основном я хотел бы обновить свой токен и повторно отправить свой запрос, когда токен доступа истек; однако я не хочу обновить мой токен, если это действительно отказанный запрос из-за указанной роли.
какие мысли?
1 ответов
Как отмечено в моем ответе на комментарий Кори Сильвы, атрибут авторизации Web API всегда возвращает 401 unauthorized как для аутентификации, так и для авторизации.
см. статью и поток ниже:
http://leastprivilege.com/2014/10/02/401-vs-403/
почему AuthorizeAttribute перенаправляет на страницу входа для сбоев аутентификации и авторизации?
похоже, что их два опции:
-
когда я храню токен, полученный с моего сервера авторизации в localStorage, я также сохраняю срок действия токена. В функции interceptor responseError я сравниваю срок действия сохраненного маркера с текущим временем 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; }
-
используйте принятый ответ в потоке 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, чтобы коды ошибок немного яснее для клиента.