[.net] ASP.NET MVC에서 권한 부여 특성 재정의

거의 모든 컨트롤러 (및 해당 작업)에 권한이 부여되기를 원하기 때문에 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();
    }
}


답변

ASP.NET MVC 4는 AllowAnonymous 특성 을 추가하여이 문제를 ‘수정’한 것 같습니다 .

David Hayden은 이에 대해 다음같이 썼습니다 .

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

    // ...
}


답변

내 개인적인 생각은 컨트롤러를 분할하는 것입니다. 인증이 필요하지 않은 작업을 위해 다른 컨트롤러를 생성하십시오.

또는 다음을 가질 수 있습니다.

  • BaseController
    인증이 필요하지 않습니다. 여기에 모든 “기본 항목”이 있습니다. :).

  • BaseAuthController : BaseController
    여기에있는 모든 작업에는 인증이 필요합니다.

이렇게하면 특정 클래스에서 파생하여 원할 때 인증을받을 수 있습니다.


답변

다른 권한이 부여 된 컨트롤러에서 하나의 작업을 승인하지 않으려면 다음과 같이 할 수 있습니다.

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


답변