使用 declarative_authorization 保护敏感属性
使用 declarative_authorization 按角色保护属性的好方法是什么?例如,用户可以编辑他的联系信息,但不能编辑他的角色。
我的第一个倾向是为不同的场景创建多个控制器操作。我很快意识到,随着受保护属性数量的增加,这会变得多么笨拙。为用户角色执行此操作是一回事,但我可以想象多个受保护的属性。添加大量控制器操作和路线感觉不太对。
我的第二个倾向是围绕特定的敏感属性创建权限,然后使用 declarative_authorizations 提供的 View hepers 包装表单元素。然而,模型和控制器方面在我看来有点模糊。建议会很棒。
请建议使用 declarative_authorizations 按角色保护属性的最佳方法。
What's a cool way to protect attributes by role using declarative_authorization? For example, a user can edit his contact information but not his role.
My first inclination was to create multiple controller actions for different scenarios. I quickly realized how unwieldy this could become as the number of protected attributes grows. Doing this for user role is one thing, but I can imagine multiple protected attributes. Adding a lot controller actions and routes doesn't feel right.
My second inclination was to create permissions around specific sensitive attributes and then wrap the form elements with View hepers provided by declarative_authorizations. However, the model and controller aspect of this is a bit foggy in my mind. Suggestions would be awesome.
Please advise on the best way to protect attributes by role using declarative_authorizations.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
编辑2011-05-22
从 3.1RC 开始,Rails 中现在也有类似的东西 https:/ /github.com/rails/rails/blob/master/activerecord/test/cases/mass_assignment_security_test.rb 所以我建议现在就走这条路。
原始答案
我只需将之前使用的内容移植到 Rails 3 中。我从未专门使用过声明性授权,但这非常简单明了,您应该能够适应它。
Rails 3 添加了
mass_assignment_authorizer
,这使得这一切真正实现简单的。我使用该链接的教程作为基础,并通过类继承并将属性分组为角色,使其更好地适合我的域模型。在模型中
在控制器中
lib/active_record/acts_as_accessible.rb
spec/lib/active_record/acts_as_accessible.rb
EDIT 2011-05-22
Something similar is now in Rails as of 3.1RC https://github.com/rails/rails/blob/master/activerecord/test/cases/mass_assignment_security_test.rb so I would suggest going that route now.
ORIGINAL ANSWER
I just had to port what I had been using previously to Rails 3. I've never used declarative authorization specifically, but this is pretty simple and straightforward enough that you should be able to adapt to it.
Rails 3 added
mass_assignment_authorizer
, which makes this all really simple. I used that linked tutorial as a basis and just made it fit my domain model better, with class inheritance and grouping the attributes into roles.In model
In controller
lib/active_record/acts_as_accessible.rb
spec/lib/active_record/acts_as_accessible.rb
对我来说,这个过滤问题应该在控制器级别应用。
您需要在某个地方定义如何决定哪些属性对于给定用户是可写的。
然后,在应用程序控制器中,您可以定义一个方法来过滤参数。
最后,在控制器操作中,您可以使用此过滤器:
想法是,您可以在每个模型上定义 allowed_params,并让每个模型的控制器使用相同的过滤器方法。您可以通过在应用程序控制器中使用一个方法来保存一些样板文件,该方法可以发出前置过滤器,如下所示:
这些示例旨在说明性而非确定性,我希望它们有助于实现此目的。
To me this filtering problem is something that should be applied at the controller level.
You'll want to have something somewhere that defines how to decide which attributes are writeable for a given user.
Then, in the application controller you can define a method to filter parameters.
And finally in your controller action you can use this filter:
The idea is that you could then define allowed_params on each of your models, and have the controllers for each of these use the same filter method. You could save some boilerplate by having a method in application controller that spits out a before filter, like this:
These examples are intended to be illustrative rather than definitive, I hope they help with the implementation of this.
我会使用 scoped_attr_accessible ,它看起来正是您正在寻找的。只需在所有模型的请求开始时设置范围即可。
为此,请在 application_controller.rb 中使用
before_filter
:I'd use scoped_attr_accessible, which looks like just what you're looking for. Only you need to set the scope at the start of a request for all models.
To do that, use a
before_filter
in your application_controller.rb:我会避免基于模型中用户访问的每个解决方案,因为它似乎存在潜在危险。我会尝试这种方法:
然后在您的控制器中将更新操作从:
更改为
I would avoid every solution based on user access in model because it seems potentially dangerous. I would try this approach:
Then in your controller change your update action from:
to
Rails 3.1+ 为此目的提供了一个 +assign_attributes+ 方法 - http://apidock.com/rails/ ActiveRecord/AttributeAssignment/assign_attributes。
Rails 3.1+ comes with a +assign_attributes+ method for this purpose - http://apidock.com/rails/ActiveRecord/AttributeAssignment/assign_attributes.