ASP.NETMVCの承認属性をオーバーライドする


83

ほとんどすべてのコントローラー(およびそれらのアクション)を承認する必要があるため、Authorize属性を適用したMVCコントローラー基本クラスがあります。

ただし、コントローラーと別のコントローラーのアクションを許可しないようにする必要があります。[Authorize(false)]か何かで飾れるようにしたかったのですが、これは利用できません。

何か案は?

回答:


100

編集:ASP.NET MVC 4以降、最善のアプローチは、組み込みのAllowAnonymous属性を使用することです。

以下の回答は、ASP.NETMVCの以前のバージョンを参照しています

オプションのboolパラメーターを使用して標準のAuthorizeAttributeから継承するカスタム承認属性を作成して、承認が必要かどうかを指定できます。

public class OptionalAuthorizeAttribute : AuthorizeAttribute
{
    private readonly bool _authorize;

    public OptionalAuthorizeAttribute()
    {
        _authorize = true;
    }

    public OptionalAuthorizeAttribute(bool authorize)
    {
        _authorize = authorize;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if(!_authorize)
            return true;

                    return base.AuthorizeCore(httpContext);
    }
}

次に、その属性でベースコントローラーを装飾できます。

[OptionalAuthorize]
public class ControllerBase : Controller
{
}

また、認証が不要なコントローラーの場合は、「false」を指定してオーバーライドを使用するだけです。

[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}

私はこれについて考えましたが、もっと簡単な解決策を望んでいました。ただし、「彼ら」が提供しなかった場合は、ソリューションが最適です。
アンドレイRînea

2
[AllowAnonymous]属性を使用することをお勧めします。
ジェイダー2015

待ってください...コントローラーは特定のタイプのトップレベルクラスの属性のみを尊重しますか?
Triynko 2015年

AllowAnonymousを使用する方が実際に優れている理由を知っていますか?あなたがより細かいコントロールを持っているからです。私の場合、特定の環境でのみ承認エンドポイントを無効にすることを検討しています。たとえば、ローカルホストでは必要ありません。これにより、startup.csで行うよりも洗練されたソリューションが提供されます。私たちは11年後にここで話している。
sksallaj


15

これについての私の個人的な見解は、コントローラーを分割することです。別のコントローラーを作成するだけです。認証を必要としないアクションの場合。

またはあなたが持つことができます:

  • BaseController
    認証は必要ありません-ここにすべての「基本的なもの」があります:)。

  • BaseAuthController : BaseController
    ここでのすべてのアクションには認証が必要です。

そうすれば、特定のクラスから派生するだけで、必要なときに認証を行うことができます。


6

他の方法で許可されたコントローラーで1つのアクションを許可しないようにする場合は、次のようにします。

public class RequiresAuthorizationAttribute : ActionFilterAttribute
{
    private readonly bool _authorize;

    public RequiresAuthorizationAttribute()
    {
        _authorize = true;
    }

    public RequiresAuthorizationAttribute(bool authorize)
    {
        _authorize = authorize;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var overridingAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof (RequiresAuthorizationAttribute), false);

        if (overridingAttributes.Length > 0 && overridingAttributes[0] as RequiresAuthorizationAttribute != null && !((RequiresAuthorizationAttribute)overridingAttributes[0])._authorize)
            return;

        if (_authorize)
        {
            //redirect if not authenticated
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                //use the current url for the redirect
                var redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;

                //send them off to the login page
                //var redirectUrl = string.Format("?RedirectUrl={0}", redirectOnSuccess);
                var loginUrl = LinkBuilder.BuildUrlFromExpression<HomeController>(filterContext.RequestContext, RouteTable.Routes,
                                                                                  x => x.Login(redirectOnSuccess));
                filterContext.HttpContext.Response.Redirect(loginUrl, true);
            }
        }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.