ActionFilterAttribute
でリダイレクトを行う最良の方法は何ですか。 ActionFilterAttribute
というIsAuthenticatedAttributeFilter
があり、セッション変数の値を確認しました。変数がfalseの場合、アプリケーションがログインページにリダイレクトするようにします。ルート名SystemLogin
を使用してリダイレクトしたいと思いますが、この時点でのリダイレクト方法は問題ありません。
filterContext.Resultを設定
ルート名:
filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);
次のようなこともできます:
filterContext.Result = new ViewResult
{
ViewName = SharedViews.SessionLost,
ViewData = filterContext.Controller.ViewData
};
RedirectToAction
を使用する場合:
保護されたRedirectToAction
を単に呼び出すコントローラー(できればそのベースコントローラーで)RedirectToAction
メソッドを公開できます。 System.Web.Mvc.Controller
。このメソッドを追加すると、フィルターからyourRedirectToAction
へのパブリックコールが可能になります。
public new RedirectToRouteResult RedirectToAction(string action, string controller)
{
return base.RedirectToAction(action, controller);
}
次に、フィルターは次のようになります。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (SomeControllerBase) filterContext.Controller;
filterContext.Result = controller.RedirectToAction("index", "home");
}
リダイレクトの代わりに、独自のコードを呼び出している場合、これを使用できます:
actionContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { controller = "Home", action = "Error" })
);
actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);
これは純粋なリダイレクトではありませんが、不必要なオーバーヘッドなしで同様の結果をもたらします。
私はMVC4を使用しています。承認違反時にカスタムHTML画面をリダイレクトするには、次のアプローチを使用しました。
拡張AuthorizeAttribute
say CutomAuthorizer
は、OnAuthorization
およびHandleUnauthorizedRequest
をオーバーライドします
CustomAuthorizer
をRegisterGlobalFilters
に登録します。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizer());
}
unAuthorized
アクセス呼び出しHandleUnauthorizedRequest
を識別し、以下に示すように関連するコントローラーアクションにリダイレクトします。
public class CustomAuthorizer : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
bool isAuthorized = IsAuthorized(filterContext); // check authorization
base.OnAuthorization(filterContext);
if (!isAuthorized && !filterContext.ActionDescriptor.ActionName.Equals("Unauthorized", StringComparison.InvariantCultureIgnoreCase)
&& !filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.Equals("LogOn", StringComparison.InvariantCultureIgnoreCase))
{
HandleUnauthorizedRequest(filterContext);
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary{{ "controller", "LogOn" },
{ "action", "Unauthorized" }
});
}
}
AuthorizeAttribute
を再実装または拡張したいようです。その場合、ASP.NET MVCがより多くの作業を行うために、ActionFilterAttribute
ではなく、それを継承することを確認する必要があります。
また、beforeアクションメソッドで実際の作業のいずれかを行うことを確認する必要があります。できた。
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
// Do whatever checking you need here
// If you want the base check as well (against users/roles) call
base.OnAuthorization(filterContext);
}
}
次のスニペットを試してください、それはかなり明確であるはずです:
public class AuthorizeActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(FilterExecutingContext filterContext)
{
HttpSessionStateBase session = filterContext.HttpContext.Session;
Controller controller = filterContext.Controller as Controller;
if (controller != null)
{
if (session["Login"] == null)
{
filterContext.Cancel = true;
controller.HttpContext.Response.Redirect("./Login");
}
}
base.OnActionExecuting(filterContext);
}
}
Ajaxリクエストを使用している場合にも考慮に入れるソリューションを次に示します。
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace YourNamespace{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeCustom : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext context) {
if (YourAuthorizationCheckGoesHere) {
string area = "";// leave empty if not using area's
string controller = "ControllerName";
string action = "ActionName";
var urlHelper = new UrlHelper(context.RequestContext);
if (context.HttpContext.Request.IsAjaxRequest()){ // Check if Ajax
if(area == string.Empty)
context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(controller, action))}');</script>");
else
context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(area, controller, action))}');</script>");
} else // Non Ajax Request
context.Result = new RedirectToRouteResult(new RouteValueDictionary( new{ area, controller, action }));
}
base.OnActionExecuting(context);
}
}
}
これは私のために働く(asp.netコア2.1)
using JustRide.Web.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace MyProject.Web.Filters
{
public class IsAuthenticatedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.HttpContext.User.Identity.IsAuthenticated)
context.Result = new RedirectToActionResult(nameof(AccountController.Index), "Account", null);
}
}
}
[AllowAnonymous, IsAuthenticated]
public IActionResult Index()
{
return View();
}
コントローラーを継承し、アクションフィルター内で使用できます。
actionFilterAttributeクラス内:
if( filterContext.Controller is MyController )
if(filterContext.HttpContext.Session["login"] == null)
(filterContext.Controller as MyController).RedirectToAction("Login");
ベースコントローラー内:
public class MyController : Controller
{
public void RedirectToAction(string actionName) {
base.RedirectToAction(actionName);
}
}
短所これは、すべてのコントローラーを「MyController」クラスから継承するように変更することです