source

ASP.NET MVC에서 전체 영역에 대한 권한을 설정하려면 어떻게 해야 합니까?

factcode 2023. 6. 8. 22:38
반응형

ASP.NET MVC에서 전체 영역에 대한 권한을 설정하려면 어떻게 해야 합니까?

관리자 영역이 있고 관리자만 해당 영역에 들어가도록 합니다.Admin 영역의 모든 컨트롤러에 Authorized 특성을 추가하는 것을 고려했습니다.우아한 솔루션이 있거나 프레임워크 자체에 이 기능이 없는 것입니까?

편집: 죄송합니다. 제가 진작에 이 말을 했어야 했습니다.AuthorizedAttribute에서 파생된 사용자 지정 AuthorizedAttribute를 사용하고 있습니다.

웹.config 기반 보안은 MVC 응용 프로그램에서 거의 사용되지 않아야 합니다.그 이유는 여러 URL이 컨트롤러에 영향을 줄 수 있으며 이러한 검사를 Web.config에 넣으면 항상 무언가가 누락되기 때문입니다.컨트롤러는 영역과 연결되지 않으며 경로는 영역과 연결됩니다.MVC 컨트롤러 공장은 충돌이 없는 경우 영역/폴더의 컨트롤러에 대해 영역이 아닌 요청을 처리할 수 있습니다.

예를 들어 기본 프로젝트 구조를 사용하여 AdminDefaultController가 있는 Admin 영역을 추가하면 /Admin/AdminDefault/Index 및 /AdminDefault/Index를 통해 이 컨트롤러를 누를 수 있습니다.

지원되는 유일한 솔루션은 속성을 컨트롤러 기본 클래스에 배치하고 영역 내의 각 컨트롤러가 해당 기본 클래스를 하위 클래스로 분류하도록 하는 것입니다.

저는 방금 이 같은 문제를 조사하고 있습니다.영역별로 컨트롤러를 보호할 수 없기 때문에 더 간단한 옵션이 떠오릅니다.

컨트롤러를 재정의하는 각 영역에 대한 기본 컨트롤러 정의를 만들고 여기에 보안 요구 사항을 추가합니다.그런 다음 영역의 각 컨트롤러가 컨트롤러 대신 영역 컨트롤러를 재정의하는지 확인하면 됩니다.예:

/// <summary>
/// Base controller for all Admin area
/// </summary>
[Authorize(Roles = "Admin")]
public abstract class AdminController : Controller { }

관리 영역의 각 컨트롤러를 이 기본에서 파생해야 합니다.

public class HomeController : AdminController
{
    // .. actions
}

적어도 지역의 보안을 정의할 수 있는 단일 지점이 있습니다.

이제 막 시작한 일인데...하지만 아직까지는 이게 저한테 꽤 효과가 있어요.

사용자 지정 AuthorizeAttribute 클래스를 만들고 이 클래스를 RegisterGlobalFilters 함수에 추가합니다.

사용자 지정 중AuthorizeAttribute 현재 위치에 따라 다양한 조건을 확인합니다.

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomAuthorizeAttribute());
        filters.Add(new HandleErrorAttribute());
    }
}

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var routeData = httpContext.Request.RequestContext.RouteData;
        var controller = routeData.GetRequiredString("controller");
        var action = routeData.GetRequiredString("action");
        var area = routeData.DataTokens["area"];
        var user = httpContext.User;
        if (area != null && area.ToString() == "Customer")
        {
            if (!user.Identity.IsAuthenticated)
                return false;
        }
        else if (area != null && area.ToString() == "Admin")
        {
            if (!user.Identity.IsAuthenticated)
                return false;
            if (!user.IsInRole("Admin"))
                return false;
        }
        return true;
    }
}

모든 관리 코드가 한 컨트롤러에 있는 경우 전체 클래스에 인증을 추가합니다.

[Authorize]
public class AdminController : Controller
{
     .......
}

현재 승인된 답변은 개발자가 컨트롤러 또는 작업에 대해 해당 새 기본 클래스를 항상 상속해야 하므로 가장 안전한 솔루션이 아닙니다("블랙리스트", 작업이 수동으로 제한되지 않는 한 사용자가 모든 작업에 액세스할 수 있도록 허용).이것은 특히 당신의 의식에 익숙하지 않은 새로운 개발자들이 프로젝트에 소개될 때 문제를 야기합니다.특히 몇 주, 몇 달 또는 몇 년 동안 프로젝트에서 눈을 떼면 해당 컨트롤러 클래스를 상속받는 것을 잊기 쉽습니다.개발자가 상속을 잊으면 프로젝트에 보안 취약성이 있는 것이 분명하지 않습니다.

이 문제에 대한 보다 안전한 해결책은 모든 요청에 대한 액세스를 거부한 다음 각 수행을 수행에 대한 액세스가 허용되는 역할("화이트리스트", 수동으로 허용되지 않는 한 모든 사용자에 대한 액세스 금지)로 장식하는 것입니다.이제 개발자가 적절한 인증을 화이트리스트에 추가하는 것을 잊어버린 경우 사용자가 이를 알려주면 다른 컨트롤러에서 액세스 권한을 부여하는 방법을 확인하는 것처럼 간단합니다.그러나 적어도 큰 보안 취약성은 없습니다.

App_Start/FilterConfig.cs 파일에서 FilterConfig 클래스를 수정합니다.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        ...

        //Deny access to all controllers and actions so that only logged in Administrators can access them by default
        filters.Add(new System.Web.Mvc.AuthorizeAttribute() { Roles = "Administrator" });
    }

이렇게 하면 사용자가 관리자로 로그인하지 않으면 모든 작업에 액세스할 수 없습니다.그런 다음 인증된 다른 사용자가 액세스할 수 있도록 원하는 각 작업에 대해 다음과 같이 장식합니다.[OverrideAuthorization]그리고.[Authorize].

비즈니스 로직에서 이를 통해 권한 없는 사용자가 어떤 기능에도 액세스할 수 있을지 걱정할 필요 없이 다양한 방식으로 권한 부여 특성을 사용할 수 있습니다.다음은 몇 가지 예입니다.

1 - 로그인한 관리자 및 발송자 사용자만 액세스할 수 있습니다.Index()메서드 가져오기 및 게시.

public class MarkupCalculatorController : Controller //Just continue using the default Controller class.
{
    // GET: MarkupCalculator
    [OverrideAuthorization]
    [Authorize(Roles = "Administrator,Dispatcher")]
    public ActionResult Index()
    {
        //Business logic here.

        return View(...);
    }

    // POST: DeliveryFeeCalculator
    [HttpPost]
    [ValidateAntiForgeryToken]
    [OverrideAuthorization]
    [Authorize(Roles = "Administrator,Dispatcher")]
    public ActionResult Index([Bind(Include = "Price,MarkedupPrice")] MarkupCalculatorVM markupCalculatorVM)
    {
        //Business logic here.

        return View(...);
    }
}

2 - 인증된 사용자만 홈 컨트롤러의 시스템에 액세스할 수 있습니다.Index()방법.

public class HomeController : Controller
{
    [OverrideAuthorization]
    [Authorize] //Allow all authorized (logged in) users to use this action
    public ActionResult Index()
    {
        return View();
    }

}

3 - 인증되지 않은 사용자(즉, 익명 사용자)가 다음을 사용하여 메서드에 액세스하도록 허용할 수 있습니다.[AllowAnonymous] 글로벌 으로 덮어쓰므로 사용자가 .[OverrideAuthorization]기여하다.

    // GET: /Account/Login
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

    //
    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        ...
    }

4 - 관리자만이 부족한 방법에 액세스할 수 있습니다.[Authorize]기여하다.

public class LocationsController : Controller
{

    // GET: Locations
    public ActionResult Index()
    {
        //Business logic here.
        return View(...);
    }
}

메모 몇 개.

다음을 사용해야 합니다.[OverrideAuthorization]특정 작업에 대한 액세스를 특정 역할로 제한하려는 경우 속성을 지정합니다.그렇지 않으면,[Authorize]글로벌 필터 때문에 다른 역할(예: 디스패치 등)을 지정하더라도 속성 속성은 무시되고 기본 역할(예: 관리자)만 허용됩니다.인증되지 않은 사용자는 로그인 화면으로 리디렉션됩니다.

사용[OverrideAuthorization]attribute를 사용하면 작업이 사용자가 설정한 글로벌 필터를 무시합니다.따라서 다음을 다시 적용해야 합니다.[Authorize]작업의 보안을 유지하기 위해 재정의를 사용할 때마다 속성을 지정합니다.

전체 영역 및 컨트롤러에 대해

요청하신 대로 영역별로 제한하려면 다음을 입력합니다.[OverrideAuthorization]그리고.[Authorize]개별 작업 대신 컨트롤러의 속성을 사용할 수 있습니다.

영역 이름 및 슬래시 사용AuthorizeAreaFolderstartup.cs 에서 저를 위해 일했습니다.

services.AddRazorPages()
        .AddRazorPagesOptions(options => options.Conventions.AuthorizeAreaFolder("Admin", "/"))
        .WithRazorPagesAtContentRoot();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy", policy => policy.RequireRole("Administrator"));
});
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity","/Account/Manage", "AdminPolicy");
});

매우 조잡하게 나는 당신이 이런 것을 원한다고 믿습니까?

신속하고 더러운 역할 관리

[Authorize(Roles = "Admins")]
public ActionResult Register()
{
  ViewData["roleName"] = new SelectList(Roles.GetAllRoles(), "roleName");
  ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
  return View();
}

언급URL : https://stackoverflow.com/questions/2319157/how-can-we-set-authorization-for-a-whole-area-in-asp-net-mvc

반응형