18

私のAngularアプリケーションは、記事シリーズhttp://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-netで概説されているように、ベアラートークンを利用しています-アイデンティティ/ . アクセストークンの有効期限が切れたときに(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;
        }

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

何かご意見は?

4

1 に答える 1

15

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

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

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 を使用して、エラー コードがクライアントに少しわかりやすくなるようにします。

于 2014-11-13T02:05:19.197 に答える