ほとんどすべてのコントローラー(およびそれらのアクション)を承認する必要があるため、Authorize属性を適用したMVCコントローラー基本クラスがあります。
ただし、コントローラーと別のコントローラーのアクションを許可しないようにする必要があります。[Authorize(false)]
か何かで飾れるようにしたかったのですが、これは利用できません。
何か案は?
回答:
編集: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();
}
}
[AllowAnonymous]
属性を使用することをお勧めします。
ASP.NET MVC 4は、AllowAnonymous属性を追加することでこれを「修正」したようです。
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
// ...
}
// ...
}
他の方法で許可されたコントローラーで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);
}
}
}
}