거의 모든 컨트롤러 (및 해당 작업)에 권한이 부여되기를 원하기 때문에 Authorize 특성을 적용한 MVC 컨트롤러 기본 클래스가 있습니다.
그러나 권한이없는 다른 컨트롤러의 작업과 컨트롤러가 필요합니다. 나는 [Authorize(false)]
또는 무언가 로 그들을 장식하고 싶었지만 이것은 사용할 수 없습니다.
어떤 아이디어?
답변:
편집 : ASP.NET MVC 4 이후 가장 좋은 방법은 기본 제공 AllowAnonymous 특성 을 사용하는 것입니다.
아래 답변은 이전 버전의 ASP.NET MVC를 나타냅니다.
선택적 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 특성 을 추가하여이 문제를 '수정'한 것 같습니다 .
David Hayden은 이에 대해 다음 과 같이 썼습니다 .
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
// ...
}
// ...
}
다른 권한이 부여 된 컨트롤러에서 하나의 작업을 승인하지 않으려면 다음과 같이 할 수 있습니다.
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);
}
}
}
}