私のウェブサイトでは、保護されたコントローラー(またはアクション)の次の動作が必要です
ユーザーが通常のリクエストをログインページにリダイレクトした場合(これは簡単に実行できました)
リクエストが Ajax タイプ Request.IsAjaxRequest()==true
の場合、ステータス コード 401 を返す
このためのフィルターを作成するにはどうすればよいですか??
私のウェブサイトでは、保護されたコントローラー(またはアクション)の次の動作が必要です
ユーザーが通常のリクエストをログインページにリダイレクトした場合(これは簡単に実行できました)
リクエストが Ajax タイプ Request.IsAjaxRequest()==true
の場合、ステータス コード 401 を返す
このためのフィルターを作成するにはどうすればよいですか??
public class MyCustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//if ajax request set status code and end Response
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.HttpContext.Response.End();
}
base.HandleUnauthorizedRequest(filterContext);
}
}
上記のようなフィルタを作成すると、リクエストが ajax 経由で行われた場合、不正なリクエストに対してステータス コード 401 が返されます。
jQueryを使用している場合は、次のようにできます
jQuery.ajax({
statusCode: {
401: function() {
alert('unauthrized');
},
/*other options*/
});
受け入れられた回答に加えて、FormsAuthentication がログイン ページにリダイレクトされないようにするために、このコード行を挿入する必要がありました。
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
次に、filterContext.HttpContext.Response.End(); を削除しました。
var unauthorizedResult = new JsonResult
{
Data = new ErrorResult() {Success = 0, Error = "Forbidden"},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
// status code
filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
// return data
filterContext.Result = unauthorizedResult;
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
}
問題はAJAXリクエストではなく、フォーム認証を使用しているため、HTTP401Unauthorized応答が返されます。この応答コードは、代わりにHTTP302応答を使用してユーザーエージェントをログインページにリダイレクトする必要があることをフレームワークに通知します。そのため、「通常の」リクエストリダイレクトを簡単に設定できました。これは自動的に行われます。
あなたの質問に答えるために、私は同様の問題を抱えていました、そして私が最終的に得た解決策はフォーム認証を使用していませんでした。代わりに、両方のケースを手動で処理するカスタム認証属性を実装しました。これが最善のアプローチかどうかはわかりませんが、機能します。他の人がこの解決策についてどう思っているか、または他にどのような解決策があるかに興味があります。
幸いなことに、あなたはまだ使用することができますFormsAuthentication
Cookieを処理するクラスですが、Web.configファイルからフォーム認証構成を削除する必要があります。ユーザーがログインするときにFormsAuthentication.SetAuthCookie
、Cookieを設定します(おそらくこれはすでに行っています)。次に、承認属性で、リクエストからCookieを取得し、FormsAuthentication.Decrypt
それを復号化するために使用します。それが存在し、有効である場合、HttpContext
フォーム認証はもはやあなたのためにそれを行わないので、あなたはこのクッキーに基づいてユーザーを設定します。そうでない場合は、AJAX呼び出しであるかどうかに応じて、ログインページにリダイレクトするか、401を返します。
HttpUnauthorizedResultを返すだけです。
注:これにより、MVC フレームワークがログイン ページに戻る可能性があります。
public ActionResult FailResult()
{
return new HttpUnauthorizedResult();
}
ajaxonlyを使用して、ajax actionresult へのアクセスを制限できます
簡単な方法は、SignIn アクションでチェックを行うことです
public ActionResult SignIn()
{
if (Request.IsAjaxRequest())
{
// you could return a partial view that has this script instead
return Content("<script>window.location = '" + Url.Action("SignIn", "Account") + "'</script>");
}
...
return View();