【发布时间】:2013-02-08 00:59:00
【问题描述】:
换句话说,这是一个非常愚蠢的想法吗?
[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);
}
}
更新 在我们拥有极其精细的角色权限的情况下,我试图避免以下情况,因为角色是基于每个客户端设置并附加到用户组:
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 是否更安全或更好的做法?
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
return;
}
var path = filterContext.HttpContext.Request.Path;
var verb = filterContext.HttpContext.Request.HttpMethod;
// these values combined are our roleName
string roleName = String.Format("{0}/{1}", path, verb);
if (!filterContext.HttpContext.User.IsInRole(roleName))
{
// role auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
// P.S. I want to tell the logged in user they don't
// have access, not ask them to login. They are already
// logged in!
return;
}
//
base.OnAuthorization(filterContext);
}
这或许更能说明问题:
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;
}
【问题讨论】:
标签: asp.net-mvc attributes asp.net-mvc-3