web-dev-qa-db-ja.com

ベアラートークンの有効期限が切れているか、承認されているかを確認する

私の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;
        }

私はさまざまなことを試していましたが、基本的には、トークンを更新して、アクセストークンの有効期限が切れたときにリクエストを再送信します。ただし、指定されたロールが原因で本当に拒否されたリクエストである場合、トークンを更新したくありません。

何かご意見は?

17
mmoreno79

Cory Silvaのコメントに対する私の返答で述べたように、Web APIのAuthorize属性は、認証と承認の両方で常に401 unauthorizedを返します。

以下の記事とスレッドを参照してください。

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

AuthorizeAttributeが認証と承認の失敗のためにログインページにリダイレクトするのはなぜですか?

2つのオプションがあるようです。

  1. 許可サーバーから取得したトークンをlocalStorageに保管するとき、トークンの有効期限も保管します。インターセプターのresponseError関数で、保存されているトークンの有効期限を現在の日時と比較します。有効期限が切れていると判断された場合は、トークンを更新してリクエストを再送信してください。

    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を使用するつもりです。

15
mmoreno79