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


83

거의 모든 컨트롤러 (및 해당 작업)에 권한이 부여되기를 원하기 때문에 Authorize 특성을 적용한 MVC 컨트롤러 기본 클래스가 있습니다.

그러나 권한이없는 다른 컨트롤러의 작업과 컨트롤러가 필요합니다. 나는 [Authorize(false)]또는 무언가 로 그들을 장식하고 싶었지만 이것은 사용할 수 없습니다.

어떤 아이디어?

답변:


100

편집 : 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();
    }
}

나는 이것을 생각했지만 더 간단한 해결책을 원했습니다. 그러나 "그들"이 하나를 제공하지 않았다면 귀하의 솔루션이 최상의 솔루션입니다.
Andrei Rînea 2009

2
[AllowAnonymous]속성 을 사용하는 것이 좋습니다 .
Jaider 2015-09-25

잠깐 ... 컨트롤러가 특정 유형의 최상위 클래스 속성 만 존중합니까?
Triynko 2015

이것이 실제로 AllowAnonymous를 사용하는 것이 더 나은 이유를 알고 있습니까? 더 세밀하게 제어 할 수 있기 때문입니다. 제 경우에는 특정 환경에서만 인증 엔드 포인트를 비활성화하려고합니다. 예를 들어 localhost에는 필요하지 않습니다. 이것은 내 startup.cs에서하려고했던 것보다 더 우아한 솔루션을 제공합니다. 우리는 여기서 11 년 후에 이야기하고 있습니다.
sksallaj


15

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

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

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

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

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


6

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

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.