私の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;
}
私はさまざまなことを試していましたが、基本的には、トークンを更新して、アクセストークンの有効期限が切れたときにリクエストを再送信します。ただし、指定されたロールが原因で本当に拒否されたリクエストである場合、トークンを更新したくありません。
何かご意見は?
Cory Silvaのコメントに対する私の返答で述べたように、Web APIのAuthorize属性は、認証と承認の両方で常に401 unauthorizedを返します。
以下の記事とスレッドを参照してください。
http://leastprivilege.com/2014/10/02/401-vs-403/
AuthorizeAttributeが認証と承認の失敗のためにログインページにリダイレクトするのはなぜですか?
2つのオプションがあるようです。
許可サーバーから取得したトークンを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;
}
上記で参照した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を使用するつもりです。