使用反射和枚举进行 MVC 应用程序访问的逻辑控制是否安全?
尝试管理对网站的访问我创建了一些必要的实体
目标是为我的 MVC 应用程序的某些控制器的操作方法使用自定义权限属性。
[Permissions(PermissionType.SomePermissionName, CrudType.CanDelete)]
public ActionResult SomeAction()
{
}
对于此操作,我有两个枚举
[Flags]
public enum CrudType
{
CanCreate = 0x1,
CanRead = 0x2,
CanUpdate = 0x4,
CanDelete = 0x8,
}
[Flags]
public enum PermissionType
{
SomePermissionName = 0x1,
//...
}
现在我想要下面的方法来检查权限
public static bool CanAccess(RolePermissions rp, CrudType crudType)
{
var pInfo = rp.GetType().GetProperties();
var res = pInfo.FirstOrDefault(x => x.Name == crudType.ToString());
if(res != null)
{
return Convert.ToBoolean(res.GetValue(rp, null));
}
return false;
}
它效果很好,但是在这里使用反射安全吗?这是一个好的风格吗?
还有一个问题是关于这样一段代码的
var permission = PermissionService.GetByName(permissionType.ToString());
:这里我尝试使用 PermissionType
枚举中的一些命名常量从数据库获取权限对象。
在这两种情况下,正确的工作取决于枚举和某些表字段或记录之间的关系。另一方面,我有一个很好的控制逻辑的机制(在我看来)。 这是个好办法吗?
Trying to manage access to a web site I created some necessary entities
The goal is use a custom permission attribute for some controller's action method of my MVC application.
[Permissions(PermissionType.SomePermissionName, CrudType.CanDelete)]
public ActionResult SomeAction()
{
}
For this operation I have two enums
[Flags]
public enum CrudType
{
CanCreate = 0x1,
CanRead = 0x2,
CanUpdate = 0x4,
CanDelete = 0x8,
}
[Flags]
public enum PermissionType
{
SomePermissionName = 0x1,
//...
}
Now I want the method below to check permissions
public static bool CanAccess(RolePermissions rp, CrudType crudType)
{
var pInfo = rp.GetType().GetProperties();
var res = pInfo.FirstOrDefault(x => x.Name == crudType.ToString());
if(res != null)
{
return Convert.ToBoolean(res.GetValue(rp, null));
}
return false;
}
It works good but is it safe to use reflection here? Is it a good style?
One more question is about such piece of code
var permission = PermissionService.GetByName(permissionType.ToString());
Here I'm trying to get a permission object from a database using some named constant from the PermissionType
enum.
In both cases the correct work depends on relationships between enums and some table fields or records. On other side I have a good mechanism of controlling logic (as it seems to me).
Is that a good way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
另一次编辑
在您的情况下,为
RolePermissions
类创建一个只读属性ExistingPermissions
是有意义的,并将四个布尔值合并为一个CrudType
在该属性获取器内。然后你就可以执行rp.ExistingPermissions.HasFlag(permissionToCheck)
。已编辑
感谢@DevDelivery 指出了这个问题 - 很好。不幸的是,固定的解决方案并不像我希望的那么漂亮,所以在这种情况下,采用 @DevDelivery 的方法可能是有意义的。
由于您将
CrudType
作为“位字段”,因此您可以使用更简洁的方法(更少的代码和更好的可读性):与您的解决方案相比,缺点是您必须修改此方法,以防您添加更多操作(现有的
CanRead
等)。ANOTHER EDIT
In your case it would make sense to create a readonly property
ExistingPermissions
for theRolePermissions
class, and do the merging of the four booleans into oneCrudType
within that property getter. Then you can just dorp.ExistingPermissions.HasFlag(permissionToCheck)
.EDITED
Thanks to @DevDelivery for pointing out the issue - good catch. Unfortunately the fixed solution isn't as pretty as I was hoping for, so in this case it might make sense to go with @DevDelivery's approach.
Since you have your
CrudType
as "bitfields", you can use a cleaner approach (less code and better readability):The drawback compared to your solution is that you will have to modify this method in case you add more operations (to the existing
CanRead
, etc.).使用反射会对性能产生影响,并且后期绑定意味着更改枚举的名称
或者属性不会被编译器捕获。
另外,这段代码非常难以理解,因此难以维护。
这里只有 4 个选项需要检查。简单的 switch 语句更容易、更快、更简洁。
如果您试图允许更改数据库或允许第三方组件引入新权限,那么使用反射是有意义的。
Using reflection has a performance impact and the late-binding means that changing a name of a enum
or property will not get caught by the compiler.
Plus, this code is very hard to understand, thus difficult to maintain.
Here there are only 4 options to check. A simple switch statement is easier, faster, and cleaner.
Using reflection would make sense if you were trying to allow for changes to the database or for third-party components to introduce new permissions.