83

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

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

何か案は?

4

4 に答える 4

101

Edit: Since ASP.NET MVC 4 the best approach is simply to use the built-in AllowAnonymous attribute.

The answer below refers to earlier versions of ASP.NET MVC

You could create a custom authorisation attribute inheriting from the standard AuthorizeAttribute with an optional bool parameter to specify whether authorisation is required or not.

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);
    }
}

Then you can decorate your base controller with that attribute:

[OptionalAuthorize]
public class ControllerBase : Controller
{
}

and for any controllers you don't want authorisation simply use the override with a 'false' - e.g.

[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}
于 2009-04-14T11:56:23.683 に答える
77

ASP.NET MVC 4は、AllowAnonymous属性を追加することでこれを「修正」したようです。

デビッドヘイデンはこれについて書いた

[Authorize]
public class AccountController : Controller
{
    [AllowAnonymous]
    public ActionResult Login()
    {
        // ...
    }

    // ...
}
于 2012-04-25T12:16:47.370 に答える
15

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

または、次のようにすることもできます。

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

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

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

于 2009-04-14T17:50:40.977 に答える
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);
            }
        }
    }
}
于 2009-05-18T07:27:16.553 に答える