web-dev-qa-db-ja.com

ユーザーがasp.net mvc3で承認されていないときに別のページにリダイレクトする

もう読んだ

MVC 3で認証されていない場合に簡単にリダイレクトする方法 および ユーザーが認証されていないときにAccessDeniedページにリダイレクトする しかし、回答からのリンク( http:/ /wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/ )は機能しません。

置いた

[Authorize(Users = "test")]
    public class RestrictedPageController: Controller
    {

        public ActionResult Index()
        {
           return View();
        }

 ....
    }

そして、私のweb.configでは、すでに

 <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="2880" />
 </authentication>

https://stackoverflow.com/a/6770583/998696

ただし、/RestrictedPage/Indexにアクセスする場合は、(他のコントローラーから)他のページにリダイレクトする必要があります。これの代わりに、エラーは次のように表示されます。

Server Error in '/Project' Application.

The view 'LogOn' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Account/LogOn.aspx
~/Views/Account/LogOn.ascx
~/Views/Shared/LogOn.aspx
~/Views/Shared/LogOn.ascx
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml

ログインする前に、Logonページフォームは正しく表示されますが、/RestrictedPage/Indexページにアクセスすると上記のエラーが表示されます。 RestrictedPageページへのアクセスが許可されている別のユーザーでログインできます。

私の間違いはどこにあり、どのようにリダイレクトをセットアップしますか?

21
Snake Eyes

デフォルトのAuthorize属性は、ユーザーが認証されていないまたは認証されている場合に動作します許可されていません、ステータスコードを401(UnAuthorized)に設定します。フィルターがステータスコードを401に設定すると、ASP.NETフレームワークは、Webサイトでフォーム認証が有効になっているかどうかを確認し、そこで設定されたloginUrlパラメーターにリダイレクトします。

その振る舞いを変更したい場合、ユーザーが認証されているが許可されていない場合、ユーザーをAccessDeniedコントローラーにリダイレクトしたい場合、Authorize属性を拡張し、HandleUnauthorizedRequestメソッド。

例えば.

public class CustomAuthorize: AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
        else
        {
           filterContext.Result = new RedirectToRouteResult(new 
               RouteValueDictionary(new { controller = "AccessDenied" }));
        }
    }
}

必要に応じてHandleUnauthorizedRequestをオーバーライドでき、組み込みアクションの代わりにCustomAuthorize属性を使用するようにコントローラーアクションをマークする必要があります。

56
VJAI

マークの答えが好き
しかし、すべてのアクション属性を変更したくない
[Authorize]から[CustomAuthorize]へ

AccountControllerLogin()アクションを編集します
そしてビューを表示する前にRequest.IsAuthenticatedを確認してください
認証されたユーザーが/Account/Logonにアクセスすると、
/Error/AccessDeniedにリダイレクトします。

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        if (Request.IsAuthenticated)
        {
            return RedirectToAction("AccessDenied", "Error");
        }

        ViewBag.ReturnUrl = returnUrl;

        return View();
    }
5
Yuthasak

「〜/ Account/LogOn」の代わりに「/ Account/LogOn」を配置

2
karaxuna

はい、web.configで述べたとおりです。

<forms loginUrl="~/Account/LogOn" timeout="2880" />

リダイレクトは、アカウントコントローラーとログオンアクション結果を探しています。ページをリダイレクトする場合は、アカウントとログオンの代わりにそこで変更します

1
manny

AuthorizeAttributeをオーバーライドしたくないので、フィルターを使用しました

public class RedirectFilter : ActionFilterAttribute
{
   public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        if (!IsAuthorized(filterContext))
        {
            filterContext.Result =
                new RedirectToRouteResult(new RouteValueDictionary(new {controller = "AccessDenied"}));
        }
    }

    private bool IsAuthorized(ActionExecutingContext filterContext)
    {
        var descriptor = filterContext.ActionDescriptor;
        var authorizeAttr = descriptor.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute;

        if (authorizeAttr != null)
        {
            if(!authorizeAttr.Users.Contains(filterContext.HttpContext.User.ToString()))
            return false;
        }
        return true;

    }
}
1
Riddik