즉, 이것은 정말 어리석은 생각입니까?영역, 컨트롤러 및 동작에 대한 사용자 지정 AuthorizeAttribute를 어떻게 만듭니 까?
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeActionAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
// get the area, controller and action
var area = filterContext.RouteData.Values["area"];
var controller = filterContext.RouteData.Values["controller"];
var action = filterContext.RouteData.Values["action"];
string verb = filterContext.HttpContext.Request.HttpMethod;
// these values combined are our roleName
string roleName = String.Format("{0}/{1}/{2}/{3}", area, controller, action, verb);
// set role name to area/controller/action name
this.Roles = roleName;
base.OnAuthorization(filterContext);
}
}
UPDATE 나는 역할은 클라이언트 당 기준으로 설정하고 사용자 그룹에 부착하기 때문에 우리는 매우 세분화 된 역할 권한이 시나리오에서, 다음을 피하려고 노력 해요 :
public partial class HomeController : Controller
{
[Authorize(Roles = "/supplierarea/homecontroller/indexaction/")]
public virtual ActionResult Index()
{
return View();
}
[Authorize(Roles = "/supplierarea/homecontroller/aboutaction/")]
public virtual ActionResult About()
{
return View();
}
}
누군가이 라우드 정보에 액세스하고이를 역할 이름으로 사용하기 위해이 AuthorizeRouteAttribute를 작성하는 안전한 방법을 알 수 있습니까? Levi가 말한 것처럼 RouteData.Values는 안전하지 않습니다.
실행중인 httpContext.Request.Path의 사용이 더 안전하거나 더 나은 방법입니까?
enum Version
{
PathBasedRole,
InsecureButWorks,
SecureButMissingAreaName
}
string GetRoleName(AuthorizationContext filterContext, Version version)
{
//
var path = filterContext.HttpContext.Request.Path;
var verb = filterContext.HttpContext.Request.HttpMethod;
// recommended way to access controller and action names
var controller =
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var action =
filterContext.ActionDescriptor.ActionName;
var area = "oh dear...."; // mmmm, where's thearea name???
//
var insecureArea = filterContext.RouteData.Values["area"];
var insecureController = filterContext.RouteData.Values["controller"];
var insecureAction = filterContext.RouteData.Values["action"];
string pathRoleName =
String.Format("{0}/{1}", path, verb);
string insecureRoleName =
String.Format("{0}/{1}/{2}/{3}",
insecureArea,
insecureController,
insecureAction,
verb);
string secureRoleName =
String.Format("{0}/{1}/{2}/{3}",
area,
controller,
action,
verb);
string roleName = String.Empty;
switch (version)
{
case Version.InsecureButWorks:
roleName = insecureRoleName;
break;
case Version.PathBasedRole:
roleName = pathRoleName;
break;
case Version.SecureButMissingAreaName:
// let's hope they don't choose this, because
// I have no idea what the area name is
roleName = secureRoleName;
break;
default:
roleName = String.Empty;
break;
}
return roleName;
}
제안 사항이 코드에서 어떻게 작동하는지 보여주는 답변을 추가 할 수 있습니까? 우리는 지역을 사용하고 있으므로 컨트롤러와 액션뿐만 아니라이를 반영해야합니다. 관심이 없으면 컨트롤러 또는 작업 (예 :/myarea/mycontroller/myaction '; DROP TABLE members; - /)에 실제로 일치시킬 수 있습니까? 확실히 MVC는 처음부터 컨트롤러 나 액션과 일치하지 않을 것입니다. – Junto
질문에 대한 답변을 업데이트했습니다. – Levi
안녕하세요 Levi, 사용할 수 있습니다 (문자열 컨트롤러 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 문자열 동작 = filterContext.ActionDescriptor.ActionName;)하지만 같은 방법으로 영역 이름에 액세스 할 수 없습니다. 그러나 사용 가능한 AreaName이 없습니다. 어디에서 찾을 수 있습니까? 간단한 코드 예제가이 질문을 닫습니다. – Junto