asp.net-mvc – 如何创建特定于区域,控制器和操作的自定义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更安全或更好的做法? 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}",verb);
string insecureRoleName =
String.Format("{0}/{1}/{2}/{3}",insecureArea,insecureController,insecureAction,verb);
string secureRoleName =
String.Format("{0}/{1}/{2}/{3}",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;
}
解决方法请不要这样做.如果确实需要,可以使用控制器的类型或操作的MethodInfo来做出安全决策.但基于字符串的所有东西都是在寻找麻烦.请记住,没有保证路由值到实际控制器的1:1映射.如果您正在使用路由元组(a,b,c)来验证对SomeController :: SomeAction的访问,但有人发现(a,b’,c)也会触发相同的操作,那么该人可以绕过您的安全机制. 编辑以回复评论: 您可以通过filterContext参数的ActionDescriptor属性访问控制器的Type和action的MethodInfo.这是确定在MVC管道处理时将真正执行什么操作的唯一确定方法,因为您的查找可能与MVC幕后发生的事件不完全匹配.获得Type / MethodInfo /之后,您可以使用您希望的任何信息(例如其完全限定的名称)来做出安全决策. 作为一个实际示例,考虑一个带有控制器FooController的区域MyArea和一个动作TheAction.通常你通过这个URL点击这个FooController :: TheAction的方式:
并且路由给出了元组(Area =“MyArea”,Controller =“Foo”,Action =“TheAction”). 但是,您也可以通过以下URL点击FooController :: TheAction:
并且路由将给出元组(Area =“”,Action =“TheAction”).请记住,区域与路径相关联,而不是控制器.并且由于控制器可以被多个路径击中(如果定义匹配),则控制器也可以在逻辑上与多个区域相关联.这就是为什么我们告诉开发人员永远不要使用路由(或区域或< location>标记,通过扩展)来做出安全决策. 另外,你的类中有一个错误,它是可变的(它在OnAuthorization中改变它自己的Roles属性).操作过滤器属性必须是不可变的,因为它们可以被管道的某些部分缓存并重用.根据应用程序中声明此属性的位置,这会打开一个计时攻击,然后恶意网站访问者可以利用该攻击授予自己访问他希望的任何操作的权限. 有关详细信息,请参阅我的回复: > Area level security for asp.net mvc (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ASP.Net MVC 3控制器操作和打开新窗口
- asp.net-mvc – ASP.NET MVC局部视图慢?
- asp.net-mvc-2 – MVC的DataAnnotationsModelMetadataProvi
- asp.net – 防止用户在同一行上工作
- .net – SignalR长轮询在5秒内断开连接
- asp.net – 处理程序“PageHandlerFactory-ISAPI-4.0_32bit
- asp.net – asp:repeater – 部分更改时的标头
- 具有嵌套列表的ASP.NET MVC DefaultModelBinder
- 使用可靠的WPF / .NET背景学习ASP.NET MVC
- asp.net – 如何以编程方式从LDAP检索信息
- 在Asp.net中运行外部可执行文件的内存限制
- asp.net – 将Windows身份验证与表单身份验证混合
- asp.net-mvc – 如何在ASP.NET MVC的一个视图中使
- asp.net-mvc – 已经使用相同的参数类型定义了一
- asp.net-mvc – 使用实体框架4.1创建复合主键
- asp.net – 如何在javascript中检测/跟踪回发?
- asp.net-mvc – 使用NHibernate和Autofac管理多个
- ASP.NET将整数绑定到CheckBox的Checked字段
- asp.net – 第一个事件?主页Page_Load或内容页P
- ASP.NET中的401.2的customerrors
