确定不记名令牌是不是已过期或刚刚被授权

Posted

技术标签:

【中文标题】确定不记名令牌是不是已过期或刚刚被授权【英文标题】:Determine if bearer token has expired or is just authorized确定不记名令牌是否已过期或刚刚被授权 【发布时间】:2015-01-09 17:41:22 【问题描述】:

我的 Angular 应用程序正在使用文章系列http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ 中概述的不记名令牌。我已经按照分叉的示例在访问令牌过期时无缝刷新令牌(通过 401 http 代码)。

我的问题是如何根据确定的角色确定不记名令牌是否已过期或未经授权?

例如,我的 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;
        

我在玩不同的东西,但基本上,我想刷新我的令牌并在访问令牌过期时重新发送我的请求;但是,如果由于指定的角色而确实是被拒绝的请求,我不想刷新我的令牌。

有什么想法吗?

【问题讨论】:

您应该在访问具有属性 [Authorize(Roles="Admin")] 的 Web api 方法时返回 403 Forbidden。 401 用于身份验证。 嗯,经过更多的挖掘,我可能应该首先完成,显然 Web API Authorize 属性将始终返回 401 未经授权的身份验证和授权。 【参考方案1】:

正如我在对 Cory Silva 评论的回复中指出的那样,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?

看起来有两个选项:

    当我将从我的授权服务器检索到的令牌存储在 localStorage 中时,我还会存储令牌的过期时间。在拦截器 responseError 函数中,我将存储的令牌过期时间与当前日期时间进行比较。如果确定过期,刷新token,重新发送请求。

    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;
    
    

    使用我在上面引用的 *** 线程中接受的答案并创建我自己的 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,以便客户端更清楚错误代码。

【讨论】:

我也会使用第二个选项。第一个选项取决于用户计算机时间,因此如果用户更改时间,则会产生错误的行为。

以上是关于确定不记名令牌是不是已过期或刚刚被授权的主要内容,如果未能解决你的问题,请参考以下文章

在 Auth0 的 /userinfo api 端点中发送的不记名令牌是不是会过期?

gitlab令牌过期

如何知道访问令牌已过期?

Linkedin signin:无法检索访问令牌:appId或重定向uri与授权代码或授权代码已过期不匹配

为啥我的 JWT 不记名身份验证在令牌说 5 分钟后将令牌识别为过期?

腾讯先锋怎么解决token过期