20

JSONまたはhtmlを返す多くのajaxアクション(JQuery.ajaxを使用して実装)を備えたアプリケーションがあります。それらのいくつかは、許可されたユーザーだけがアクセスできるようにする必要があり、私はそれらを[Authorize]属性で装飾しました。ajax以外のアクションの場合、ユーザーが許可されていない場合、システムはユーザーをログインページ(web.configで構成されている)にリダイレクトします。

ただし、これはajaxアクションには適用されません。ユーザーが承認された場合、ページを読み込んだ後、Cookieの有効期限が切れて承認されなくなり、古いものを置き換えるhtmlブロックの代わりに、ブロック内にログインページが表示されます。

この問題を手動で解決できることはわかっています。たとえば、[Authorize]属性を削除し、ユーザーが承認されていない場合は、特別なjson /emptyhtmlを返します。しかし、すべてのアクションとajax関数を書き直す必要があるため、このソリューションは嫌いです。アクションを書き直さないようにするグローバルソリューションが必要です(カスタム承認属性、またはhttpの不正な結果のカスタム処理など)。

リクエストがajaxの場合はステータスコードを返し、リクエストがajaxでない場合はログインページにリダイレクトしたいと思います。

4

4 に答える 4

33

global.asax.csのコードにApplication_EndRequestハンドラーを追加して、302エラー(ログインページにリダイレクト)をAJAXリクエストの401(未承認)エラーに変更します。これにより、コントローラーアクションをそのままにして、クライアントを介してリダイレクトを処理できます(実際には、ユーザーがログインしていない場合にのみ、ユーザーに再度ログインさせることができます)。

protected void Application_EndRequest()
{
    // Any AJAX request that ends in a redirect should get mapped to an unauthorized request
    // since it should only happen when the request is not authorized and gets automatically
    // redirected to the login page.
    var context = new HttpContextWrapper( Context );
    if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
    {
        context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

次に、_Layout.cshtmlファイルにグローバルAJAXエラーハンドラーを追加します。このハンドラーは、401応答を受け取ったときにログインアクションにリダイレクトします。

<script type="text/javascript">
    $(function () {
        $(document).ajaxError(function (e, xhr, settings) {
            if (xhr.status == 401) {
                location = '@Url.Action( "login", "account" )';
            }
        });
    });
</script>

また、PhilHaackのブログ「フォーム認証の防止ログインページのリダイレクトを望まない場合」で概説されているテクニックのいくつかを試してみることもできます。

于 2012-03-07T21:09:33.523 に答える
1

すべてのアクションを書き直す必要はありません。組み込みAuthorizeフィルターを置き換えるカスタム フィルターを作成するだけです。

他の人が以前にやったことがあります

asp.net mvc [handleerror] [authorize] with JsonResult?

于 2012-03-07T21:02:09.390 に答える
0

Request.IsAjaxRequest()拡張メソッドを確認し、それがtrueの場合は特定のアクションを実行できます。

于 2012-03-07T21:04:36.950 に答える
0

おそらく、AccountController (またはそれがある場所) の LogOn アクションRequest.IsAjaxRequest()が true の場合、別の結果を返す可能性があります。

これは、承認されたアクションへの AJAX 呼び出しが承認に失敗した場合、LogOn アクションを介して適切な応答を返すことができる必要があることを意味します。

例えば

public ActionResult LogOn()
{
    if (Request.IsAjaxRequest())
    {
        // do appropriate response for ajax call here
    }

    return View();
}

そうすれば、大幅な書き換えを行う必要はないはずです

于 2012-03-07T21:41:35.590 に答える